diff options
author | Robin Holt <holt@sgi.com> | 2013-07-08 19:01:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-09 13:33:29 -0400 |
commit | 1b3a5d02ee070c8f9943333b9b6370f486601e0f (patch) | |
tree | 0630bd988dc285ca3af7d3520826b5f0d9e42748 | |
parent | 7b6d864b48d95e6ea1df7df64475b9cb9616dcf9 (diff) |
reboot: move arch/x86 reboot= handling to generic kernel
Merge together the unicore32, arm, and x86 reboot= command line
parameter handling.
Signed-off-by: Robin Holt <holt@sgi.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
Cc: Russ Anderson <rja@sgi.com>
Cc: Robin Holt <holt@sgi.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | Documentation/kernel-parameters.txt | 14 | ||||
-rw-r--r-- | arch/arm/kernel/process.c | 10 | ||||
-rw-r--r-- | arch/unicore32/kernel/process.c | 10 | ||||
-rw-r--r-- | arch/x86/include/asm/emergency-restart.h | 12 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/reboot.c | 111 | ||||
-rw-r--r-- | include/linux/reboot.h | 17 | ||||
-rw-r--r-- | kernel/reboot.c | 76 |
8 files changed, 107 insertions, 145 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 25dc4a0e7e48..75236f1972d9 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2681,9 +2681,17 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2681 | Run specified binary instead of /init from the ramdisk, | 2681 | Run specified binary instead of /init from the ramdisk, |
2682 | used for early userspace startup. See initrd. | 2682 | used for early userspace startup. See initrd. |
2683 | 2683 | ||
2684 | reboot= [BUGS=X86-32,BUGS=ARM,BUGS=IA-64] Rebooting mode | 2684 | reboot= [KNL] |
2685 | Format: <reboot_mode>[,<reboot_mode2>[,...]] | 2685 | Format (x86 or x86_64): |
2686 | See arch/*/kernel/reboot.c or arch/*/kernel/process.c | 2686 | [w[arm] | c[old] | h[ard] | s[oft] | g[pio]] \ |
2687 | [[,]s[mp]#### \ | ||
2688 | [[,]b[ios] | a[cpi] | k[bd] | t[riple] | e[fi] | p[ci]] \ | ||
2689 | [[,]f[orce] | ||
2690 | Where reboot_mode is one of warm (soft) or cold (hard) or gpio, | ||
2691 | reboot_type is one of bios, acpi, kbd, triple, efi, or pci, | ||
2692 | reboot_force is either force or not specified, | ||
2693 | reboot_cpu is s[mp]#### with #### being the processor | ||
2694 | to be used for rebooting. | ||
2687 | 2695 | ||
2688 | relax_domain_level= | 2696 | relax_domain_level= |
2689 | [KNL, SMP] Set scheduler's default relax_domain_level. | 2697 | [KNL, SMP] Set scheduler's default relax_domain_level. |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index b7fdd864c839..d3ca4f6915af 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -176,16 +176,6 @@ void arch_cpu_idle(void) | |||
176 | default_idle(); | 176 | default_idle(); |
177 | } | 177 | } |
178 | 178 | ||
179 | enum reboot_mode reboot_mode = REBOOT_HARD; | ||
180 | |||
181 | static int __init reboot_setup(char *str) | ||
182 | { | ||
183 | if ('s' == str[0]) | ||
184 | reboot_mode = REBOOT_SOFT; | ||
185 | return 1; | ||
186 | } | ||
187 | __setup("reboot=", reboot_setup); | ||
188 | |||
189 | /* | 179 | /* |
190 | * Called by kexec, immediately prior to machine_kexec(). | 180 | * Called by kexec, immediately prior to machine_kexec(). |
191 | * | 181 | * |
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index 93dd035a8c33..778ebba80827 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c | |||
@@ -51,16 +51,6 @@ void arch_cpu_idle(void) | |||
51 | local_irq_enable(); | 51 | local_irq_enable(); |
52 | } | 52 | } |
53 | 53 | ||
54 | static enum reboot_mode reboot_mode = REBOOT_HARD; | ||
55 | |||
56 | int __init reboot_setup(char *str) | ||
57 | { | ||
58 | if ('s' == str[0]) | ||
59 | reboot_mode = REBOOT_SOFT; | ||
60 | return 1; | ||
61 | } | ||
62 | __setup("reboot=", reboot_setup); | ||
63 | |||
64 | void machine_halt(void) | 54 | void machine_halt(void) |
65 | { | 55 | { |
66 | gpio_set_value(GPO_SOFT_OFF, 0); | 56 | gpio_set_value(GPO_SOFT_OFF, 0); |
diff --git a/arch/x86/include/asm/emergency-restart.h b/arch/x86/include/asm/emergency-restart.h index 75ce3f47d204..77a99ac06d00 100644 --- a/arch/x86/include/asm/emergency-restart.h +++ b/arch/x86/include/asm/emergency-restart.h | |||
@@ -1,18 +1,6 @@ | |||
1 | #ifndef _ASM_X86_EMERGENCY_RESTART_H | 1 | #ifndef _ASM_X86_EMERGENCY_RESTART_H |
2 | #define _ASM_X86_EMERGENCY_RESTART_H | 2 | #define _ASM_X86_EMERGENCY_RESTART_H |
3 | 3 | ||
4 | enum reboot_type { | ||
5 | BOOT_TRIPLE = 't', | ||
6 | BOOT_KBD = 'k', | ||
7 | BOOT_BIOS = 'b', | ||
8 | BOOT_ACPI = 'a', | ||
9 | BOOT_EFI = 'e', | ||
10 | BOOT_CF9 = 'p', | ||
11 | BOOT_CF9_COND = 'q', | ||
12 | }; | ||
13 | |||
14 | extern enum reboot_type reboot_type; | ||
15 | |||
16 | extern void machine_emergency_restart(void); | 4 | extern void machine_emergency_restart(void); |
17 | 5 | ||
18 | #endif /* _ASM_X86_EMERGENCY_RESTART_H */ | 6 | #endif /* _ASM_X86_EMERGENCY_RESTART_H */ |
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 39cc7f7acab3..63092afb142e 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/kdebug.h> | 25 | #include <linux/kdebug.h> |
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/crash_dump.h> | 27 | #include <linux/crash_dump.h> |
28 | #include <linux/reboot.h> | ||
28 | 29 | ||
29 | #include <asm/uv/uv_mmrs.h> | 30 | #include <asm/uv/uv_mmrs.h> |
30 | #include <asm/uv/uv_hub.h> | 31 | #include <asm/uv/uv_hub.h> |
@@ -36,7 +37,6 @@ | |||
36 | #include <asm/ipi.h> | 37 | #include <asm/ipi.h> |
37 | #include <asm/smp.h> | 38 | #include <asm/smp.h> |
38 | #include <asm/x86_init.h> | 39 | #include <asm/x86_init.h> |
39 | #include <asm/emergency-restart.h> | ||
40 | #include <asm/nmi.h> | 40 | #include <asm/nmi.h> |
41 | 41 | ||
42 | /* BMC sets a bit this MMR non-zero before sending an NMI */ | 42 | /* BMC sets a bit this MMR non-zero before sending an NMI */ |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index f7703401d6cb..563ed91e6faa 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -36,22 +36,6 @@ void (*pm_power_off)(void); | |||
36 | EXPORT_SYMBOL(pm_power_off); | 36 | EXPORT_SYMBOL(pm_power_off); |
37 | 37 | ||
38 | static const struct desc_ptr no_idt = {}; | 38 | static const struct desc_ptr no_idt = {}; |
39 | static enum reboot_mode reboot_mode; | ||
40 | enum reboot_type reboot_type = BOOT_ACPI; | ||
41 | int reboot_force; | ||
42 | |||
43 | /* | ||
44 | * This variable is used privately to keep track of whether or not | ||
45 | * reboot_type is still set to its default value (i.e., reboot= hasn't | ||
46 | * been set on the command line). This is needed so that we can | ||
47 | * suppress DMI scanning for reboot quirks. Without it, it's | ||
48 | * impossible to override a faulty reboot quirk without recompiling. | ||
49 | */ | ||
50 | static int reboot_default = 1; | ||
51 | |||
52 | #ifdef CONFIG_SMP | ||
53 | static int reboot_cpu = -1; | ||
54 | #endif | ||
55 | 39 | ||
56 | /* | 40 | /* |
57 | * This is set if we need to go through the 'emergency' path. | 41 | * This is set if we need to go through the 'emergency' path. |
@@ -64,79 +48,6 @@ static int reboot_emergency; | |||
64 | bool port_cf9_safe = false; | 48 | bool port_cf9_safe = false; |
65 | 49 | ||
66 | /* | 50 | /* |
67 | * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci] | ||
68 | * warm Don't set the cold reboot flag | ||
69 | * cold Set the cold reboot flag | ||
70 | * bios Reboot by jumping through the BIOS | ||
71 | * smp Reboot by executing reset on BSP or other CPU | ||
72 | * triple Force a triple fault (init) | ||
73 | * kbd Use the keyboard controller. cold reset (default) | ||
74 | * acpi Use the RESET_REG in the FADT | ||
75 | * efi Use efi reset_system runtime service | ||
76 | * pci Use the so-called "PCI reset register", CF9 | ||
77 | * force Avoid anything that could hang. | ||
78 | */ | ||
79 | static int __init reboot_setup(char *str) | ||
80 | { | ||
81 | for (;;) { | ||
82 | /* | ||
83 | * Having anything passed on the command line via | ||
84 | * reboot= will cause us to disable DMI checking | ||
85 | * below. | ||
86 | */ | ||
87 | reboot_default = 0; | ||
88 | |||
89 | switch (*str) { | ||
90 | case 'w': | ||
91 | reboot_mode = REBOOT_WARM; | ||
92 | break; | ||
93 | |||
94 | case 'c': | ||
95 | reboot_mode = REBOOT_COLD; | ||
96 | break; | ||
97 | |||
98 | #ifdef CONFIG_SMP | ||
99 | case 's': | ||
100 | if (isdigit(*(str+1))) { | ||
101 | reboot_cpu = (int) (*(str+1) - '0'); | ||
102 | if (isdigit(*(str+2))) | ||
103 | reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0'); | ||
104 | } | ||
105 | /* | ||
106 | * We will leave sorting out the final value | ||
107 | * when we are ready to reboot, since we might not | ||
108 | * have detected BSP APIC ID or smp_num_cpu | ||
109 | */ | ||
110 | break; | ||
111 | #endif /* CONFIG_SMP */ | ||
112 | |||
113 | case 'b': | ||
114 | case 'a': | ||
115 | case 'k': | ||
116 | case 't': | ||
117 | case 'e': | ||
118 | case 'p': | ||
119 | reboot_type = *str; | ||
120 | break; | ||
121 | |||
122 | case 'f': | ||
123 | reboot_force = 1; | ||
124 | break; | ||
125 | } | ||
126 | |||
127 | str = strchr(str, ','); | ||
128 | if (str) | ||
129 | str++; | ||
130 | else | ||
131 | break; | ||
132 | } | ||
133 | return 1; | ||
134 | } | ||
135 | |||
136 | __setup("reboot=", reboot_setup); | ||
137 | |||
138 | |||
139 | /* | ||
140 | * Reboot options and system auto-detection code provided by | 51 | * Reboot options and system auto-detection code provided by |
141 | * Dell Inc. so their systems "just work". :-) | 52 | * Dell Inc. so their systems "just work". :-) |
142 | */ | 53 | */ |
@@ -616,26 +527,10 @@ void native_machine_shutdown(void) | |||
616 | { | 527 | { |
617 | /* Stop the cpus and apics */ | 528 | /* Stop the cpus and apics */ |
618 | #ifdef CONFIG_SMP | 529 | #ifdef CONFIG_SMP |
619 | |||
620 | /* The boot cpu is always logical cpu 0 */ | ||
621 | int reboot_cpu_id = 0; | ||
622 | |||
623 | /* See if there has been given a command line override */ | ||
624 | if ((reboot_cpu != -1) && (reboot_cpu < nr_cpu_ids) && | ||
625 | cpu_online(reboot_cpu)) | ||
626 | reboot_cpu_id = reboot_cpu; | ||
627 | |||
628 | /* Make certain the cpu I'm about to reboot on is online */ | ||
629 | if (!cpu_online(reboot_cpu_id)) | ||
630 | reboot_cpu_id = smp_processor_id(); | ||
631 | |||
632 | /* Make certain I only run on the appropriate processor */ | ||
633 | set_cpus_allowed_ptr(current, cpumask_of(reboot_cpu_id)); | ||
634 | |||
635 | /* | 530 | /* |
636 | * O.K Now that I'm on the appropriate processor, stop all of the | 531 | * Stop all of the others. Also disable the local irq to |
637 | * others. Also disable the local irq to not receive the per-cpu | 532 | * not receive the per-cpu timer interrupt which may trigger |
638 | * timer interrupt which may trigger scheduler's load balance. | 533 | * scheduler's load balance. |
639 | */ | 534 | */ |
640 | local_irq_disable(); | 535 | local_irq_disable(); |
641 | stop_other_cpus(); | 536 | stop_other_cpus(); |
diff --git a/include/linux/reboot.h b/include/linux/reboot.h index 5a5d7f7e81b7..8e00f9f6f963 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h | |||
@@ -17,6 +17,23 @@ enum reboot_mode { | |||
17 | REBOOT_SOFT, | 17 | REBOOT_SOFT, |
18 | REBOOT_GPIO, | 18 | REBOOT_GPIO, |
19 | }; | 19 | }; |
20 | extern enum reboot_mode reboot_mode; | ||
21 | |||
22 | enum reboot_type { | ||
23 | BOOT_TRIPLE = 't', | ||
24 | BOOT_KBD = 'k', | ||
25 | BOOT_BIOS = 'b', | ||
26 | BOOT_ACPI = 'a', | ||
27 | BOOT_EFI = 'e', | ||
28 | BOOT_CF9 = 'p', | ||
29 | BOOT_CF9_COND = 'q', | ||
30 | }; | ||
31 | extern enum reboot_type reboot_type; | ||
32 | |||
33 | extern int reboot_default; | ||
34 | extern int reboot_cpu; | ||
35 | extern int reboot_force; | ||
36 | |||
20 | 37 | ||
21 | extern int register_reboot_notifier(struct notifier_block *); | 38 | extern int register_reboot_notifier(struct notifier_block *); |
22 | extern int unregister_reboot_notifier(struct notifier_block *); | 39 | extern int unregister_reboot_notifier(struct notifier_block *); |
diff --git a/kernel/reboot.c b/kernel/reboot.c index abb6a0483716..269ed9384cc4 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | #define pr_fmt(fmt) "reboot: " fmt | 7 | #define pr_fmt(fmt) "reboot: " fmt |
8 | 8 | ||
9 | #include <linux/ctype.h> | ||
9 | #include <linux/export.h> | 10 | #include <linux/export.h> |
10 | #include <linux/kexec.h> | 11 | #include <linux/kexec.h> |
11 | #include <linux/kmod.h> | 12 | #include <linux/kmod.h> |
@@ -24,6 +25,18 @@ int C_A_D = 1; | |||
24 | struct pid *cad_pid; | 25 | struct pid *cad_pid; |
25 | EXPORT_SYMBOL(cad_pid); | 26 | EXPORT_SYMBOL(cad_pid); |
26 | 27 | ||
28 | #if defined(CONFIG_ARM) || defined(CONFIG_UNICORE32) | ||
29 | #define DEFAULT_REBOOT_MODE = REBOOT_HARD | ||
30 | #else | ||
31 | #define DEFAULT_REBOOT_MODE | ||
32 | #endif | ||
33 | enum reboot_mode reboot_mode DEFAULT_REBOOT_MODE; | ||
34 | |||
35 | int reboot_default; | ||
36 | int reboot_cpu; | ||
37 | enum reboot_type reboot_type = BOOT_ACPI; | ||
38 | int reboot_force; | ||
39 | |||
27 | /* | 40 | /* |
28 | * If set, this is used for preparing the system to power off. | 41 | * If set, this is used for preparing the system to power off. |
29 | */ | 42 | */ |
@@ -87,7 +100,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier); | |||
87 | static void migrate_to_reboot_cpu(void) | 100 | static void migrate_to_reboot_cpu(void) |
88 | { | 101 | { |
89 | /* The boot cpu is always logical cpu 0 */ | 102 | /* The boot cpu is always logical cpu 0 */ |
90 | int cpu = 0; | 103 | int cpu = reboot_cpu; |
91 | 104 | ||
92 | cpu_hotplug_disable(); | 105 | cpu_hotplug_disable(); |
93 | 106 | ||
@@ -343,3 +356,64 @@ int orderly_poweroff(bool force) | |||
343 | return 0; | 356 | return 0; |
344 | } | 357 | } |
345 | EXPORT_SYMBOL_GPL(orderly_poweroff); | 358 | EXPORT_SYMBOL_GPL(orderly_poweroff); |
359 | |||
360 | static int __init reboot_setup(char *str) | ||
361 | { | ||
362 | for (;;) { | ||
363 | /* | ||
364 | * Having anything passed on the command line via | ||
365 | * reboot= will cause us to disable DMI checking | ||
366 | * below. | ||
367 | */ | ||
368 | reboot_default = 0; | ||
369 | |||
370 | switch (*str) { | ||
371 | case 'w': | ||
372 | reboot_mode = REBOOT_WARM; | ||
373 | break; | ||
374 | |||
375 | case 'c': | ||
376 | reboot_mode = REBOOT_COLD; | ||
377 | break; | ||
378 | |||
379 | case 'h': | ||
380 | reboot_mode = REBOOT_HARD; | ||
381 | break; | ||
382 | |||
383 | case 's': | ||
384 | if (isdigit(*(str+1))) | ||
385 | reboot_cpu = simple_strtoul(str+1, NULL, 0); | ||
386 | else if (str[1] == 'm' && str[2] == 'p' && | ||
387 | isdigit(*(str+3))) | ||
388 | reboot_cpu = simple_strtoul(str+3, NULL, 0); | ||
389 | else | ||
390 | reboot_mode = REBOOT_SOFT; | ||
391 | break; | ||
392 | |||
393 | case 'g': | ||
394 | reboot_mode = REBOOT_GPIO; | ||
395 | break; | ||
396 | |||
397 | case 'b': | ||
398 | case 'a': | ||
399 | case 'k': | ||
400 | case 't': | ||
401 | case 'e': | ||
402 | case 'p': | ||
403 | reboot_type = *str; | ||
404 | break; | ||
405 | |||
406 | case 'f': | ||
407 | reboot_force = 1; | ||
408 | break; | ||
409 | } | ||
410 | |||
411 | str = strchr(str, ','); | ||
412 | if (str) | ||
413 | str++; | ||
414 | else | ||
415 | break; | ||
416 | } | ||
417 | return 1; | ||
418 | } | ||
419 | __setup("reboot=", reboot_setup); | ||