forked from mirrors/linux
		
	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>
This commit is contained in:
		
							parent
							
								
									7b6d864b48
								
							
						
					
					
						commit
						1b3a5d02ee
					
				
					 8 changed files with 107 additions and 145 deletions
				
			
		|  | @ -2681,9 +2681,17 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | ||||||
| 			Run specified binary instead of /init from the ramdisk, | 			Run specified binary instead of /init from the ramdisk, | ||||||
| 			used for early userspace startup. See initrd. | 			used for early userspace startup. See initrd. | ||||||
| 
 | 
 | ||||||
| 	reboot=		[BUGS=X86-32,BUGS=ARM,BUGS=IA-64] Rebooting mode | 	reboot=		[KNL] | ||||||
| 			Format: <reboot_mode>[,<reboot_mode2>[,...]] | 			Format (x86 or x86_64): | ||||||
| 			See arch/*/kernel/reboot.c or arch/*/kernel/process.c | 				[w[arm] | c[old] | h[ard] | s[oft] | g[pio]] \ | ||||||
|  | 				[[,]s[mp]#### \ | ||||||
|  | 				[[,]b[ios] | a[cpi] | k[bd] | t[riple] | e[fi] | p[ci]] \ | ||||||
|  | 				[[,]f[orce] | ||||||
|  | 			Where reboot_mode is one of warm (soft) or cold (hard) or gpio, | ||||||
|  | 			      reboot_type is one of bios, acpi, kbd, triple, efi, or pci, | ||||||
|  | 			      reboot_force is either force or not specified, | ||||||
|  | 			      reboot_cpu is s[mp]#### with #### being the processor | ||||||
|  | 					to be used for rebooting. | ||||||
| 
 | 
 | ||||||
| 	relax_domain_level= | 	relax_domain_level= | ||||||
| 			[KNL, SMP] Set scheduler's default relax_domain_level. | 			[KNL, SMP] Set scheduler's default relax_domain_level. | ||||||
|  |  | ||||||
|  | @ -176,16 +176,6 @@ void arch_cpu_idle(void) | ||||||
| 		default_idle(); | 		default_idle(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| enum reboot_mode reboot_mode = REBOOT_HARD; |  | ||||||
| 
 |  | ||||||
| static int __init reboot_setup(char *str) |  | ||||||
| { |  | ||||||
| 	if ('s' == str[0]) |  | ||||||
| 		reboot_mode = REBOOT_SOFT; |  | ||||||
| 	return 1; |  | ||||||
| } |  | ||||||
| __setup("reboot=", reboot_setup); |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * Called by kexec, immediately prior to machine_kexec(). |  * Called by kexec, immediately prior to machine_kexec(). | ||||||
|  * |  * | ||||||
|  |  | ||||||
|  | @ -51,16 +51,6 @@ void arch_cpu_idle(void) | ||||||
| 	local_irq_enable(); | 	local_irq_enable(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static enum reboot_mode reboot_mode = REBOOT_HARD; |  | ||||||
| 
 |  | ||||||
| int __init reboot_setup(char *str) |  | ||||||
| { |  | ||||||
| 	if ('s' == str[0]) |  | ||||||
| 		reboot_mode = REBOOT_SOFT; |  | ||||||
| 	return 1; |  | ||||||
| } |  | ||||||
| __setup("reboot=", reboot_setup); |  | ||||||
| 
 |  | ||||||
| void machine_halt(void) | void machine_halt(void) | ||||||
| { | { | ||||||
| 	gpio_set_value(GPO_SOFT_OFF, 0); | 	gpio_set_value(GPO_SOFT_OFF, 0); | ||||||
|  |  | ||||||
|  | @ -1,18 +1,6 @@ | ||||||
| #ifndef _ASM_X86_EMERGENCY_RESTART_H | #ifndef _ASM_X86_EMERGENCY_RESTART_H | ||||||
| #define _ASM_X86_EMERGENCY_RESTART_H | #define _ASM_X86_EMERGENCY_RESTART_H | ||||||
| 
 | 
 | ||||||
| enum reboot_type { |  | ||||||
| 	BOOT_TRIPLE = 't', |  | ||||||
| 	BOOT_KBD = 'k', |  | ||||||
| 	BOOT_BIOS = 'b', |  | ||||||
| 	BOOT_ACPI = 'a', |  | ||||||
| 	BOOT_EFI = 'e', |  | ||||||
| 	BOOT_CF9 = 'p', |  | ||||||
| 	BOOT_CF9_COND = 'q', |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| extern enum reboot_type reboot_type; |  | ||||||
| 
 |  | ||||||
| extern void machine_emergency_restart(void); | extern void machine_emergency_restart(void); | ||||||
| 
 | 
 | ||||||
| #endif /* _ASM_X86_EMERGENCY_RESTART_H */ | #endif /* _ASM_X86_EMERGENCY_RESTART_H */ | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ | ||||||
| #include <linux/kdebug.h> | #include <linux/kdebug.h> | ||||||
| #include <linux/delay.h> | #include <linux/delay.h> | ||||||
| #include <linux/crash_dump.h> | #include <linux/crash_dump.h> | ||||||
|  | #include <linux/reboot.h> | ||||||
| 
 | 
 | ||||||
| #include <asm/uv/uv_mmrs.h> | #include <asm/uv/uv_mmrs.h> | ||||||
| #include <asm/uv/uv_hub.h> | #include <asm/uv/uv_hub.h> | ||||||
|  | @ -36,7 +37,6 @@ | ||||||
| #include <asm/ipi.h> | #include <asm/ipi.h> | ||||||
| #include <asm/smp.h> | #include <asm/smp.h> | ||||||
| #include <asm/x86_init.h> | #include <asm/x86_init.h> | ||||||
| #include <asm/emergency-restart.h> |  | ||||||
| #include <asm/nmi.h> | #include <asm/nmi.h> | ||||||
| 
 | 
 | ||||||
| /* BMC sets a bit this MMR non-zero before sending an NMI */ | /* BMC sets a bit this MMR non-zero before sending an NMI */ | ||||||
|  |  | ||||||
|  | @ -36,22 +36,6 @@ void (*pm_power_off)(void); | ||||||
| EXPORT_SYMBOL(pm_power_off); | EXPORT_SYMBOL(pm_power_off); | ||||||
| 
 | 
 | ||||||
| static const struct desc_ptr no_idt = {}; | static const struct desc_ptr no_idt = {}; | ||||||
| static enum reboot_mode reboot_mode; |  | ||||||
| enum reboot_type reboot_type = BOOT_ACPI; |  | ||||||
| int reboot_force; |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * This variable is used privately to keep track of whether or not |  | ||||||
|  * reboot_type is still set to its default value (i.e., reboot= hasn't |  | ||||||
|  * been set on the command line).  This is needed so that we can |  | ||||||
|  * suppress DMI scanning for reboot quirks.  Without it, it's |  | ||||||
|  * impossible to override a faulty reboot quirk without recompiling. |  | ||||||
|  */ |  | ||||||
| static int reboot_default = 1; |  | ||||||
| 
 |  | ||||||
| #ifdef CONFIG_SMP |  | ||||||
| static int reboot_cpu = -1; |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * This is set if we need to go through the 'emergency' path. |  * This is set if we need to go through the 'emergency' path. | ||||||
|  | @ -63,79 +47,6 @@ static int reboot_emergency; | ||||||
| /* This is set by the PCI code if either type 1 or type 2 PCI is detected */ | /* This is set by the PCI code if either type 1 or type 2 PCI is detected */ | ||||||
| bool port_cf9_safe = false; | bool port_cf9_safe = false; | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|  * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci] |  | ||||||
|  * warm   Don't set the cold reboot flag |  | ||||||
|  * cold   Set the cold reboot flag |  | ||||||
|  * bios   Reboot by jumping through the BIOS |  | ||||||
|  * smp    Reboot by executing reset on BSP or other CPU |  | ||||||
|  * triple Force a triple fault (init) |  | ||||||
|  * kbd    Use the keyboard controller. cold reset (default) |  | ||||||
|  * acpi   Use the RESET_REG in the FADT |  | ||||||
|  * efi    Use efi reset_system runtime service |  | ||||||
|  * pci    Use the so-called "PCI reset register", CF9 |  | ||||||
|  * force  Avoid anything that could hang. |  | ||||||
|  */ |  | ||||||
| static int __init reboot_setup(char *str) |  | ||||||
| { |  | ||||||
| 	for (;;) { |  | ||||||
| 		/*
 |  | ||||||
| 		 * Having anything passed on the command line via |  | ||||||
| 		 * reboot= will cause us to disable DMI checking |  | ||||||
| 		 * below. |  | ||||||
| 		 */ |  | ||||||
| 		reboot_default = 0; |  | ||||||
| 
 |  | ||||||
| 		switch (*str) { |  | ||||||
| 		case 'w': |  | ||||||
| 			reboot_mode = REBOOT_WARM; |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case 'c': |  | ||||||
| 			reboot_mode = REBOOT_COLD; |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| #ifdef CONFIG_SMP |  | ||||||
| 		case 's': |  | ||||||
| 			if (isdigit(*(str+1))) { |  | ||||||
| 				reboot_cpu = (int) (*(str+1) - '0'); |  | ||||||
| 				if (isdigit(*(str+2))) |  | ||||||
| 					reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0'); |  | ||||||
| 			} |  | ||||||
| 			/*
 |  | ||||||
| 			 * We will leave sorting out the final value |  | ||||||
| 			 * when we are ready to reboot, since we might not |  | ||||||
| 			 * have detected BSP APIC ID or smp_num_cpu |  | ||||||
| 			 */ |  | ||||||
| 			break; |  | ||||||
| #endif /* CONFIG_SMP */ |  | ||||||
| 
 |  | ||||||
| 		case 'b': |  | ||||||
| 		case 'a': |  | ||||||
| 		case 'k': |  | ||||||
| 		case 't': |  | ||||||
| 		case 'e': |  | ||||||
| 		case 'p': |  | ||||||
| 			reboot_type = *str; |  | ||||||
| 			break; |  | ||||||
| 
 |  | ||||||
| 		case 'f': |  | ||||||
| 			reboot_force = 1; |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		str = strchr(str, ','); |  | ||||||
| 		if (str) |  | ||||||
| 			str++; |  | ||||||
| 		else |  | ||||||
| 			break; |  | ||||||
| 	} |  | ||||||
| 	return 1; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| __setup("reboot=", reboot_setup); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * Reboot options and system auto-detection code provided by |  * Reboot options and system auto-detection code provided by | ||||||
|  * Dell Inc. so their systems "just work". :-) |  * Dell Inc. so their systems "just work". :-) | ||||||
|  | @ -616,26 +527,10 @@ void native_machine_shutdown(void) | ||||||
| { | { | ||||||
| 	/* Stop the cpus and apics */ | 	/* Stop the cpus and apics */ | ||||||
| #ifdef CONFIG_SMP | #ifdef CONFIG_SMP | ||||||
| 
 |  | ||||||
| 	/* The boot cpu is always logical cpu 0 */ |  | ||||||
| 	int reboot_cpu_id = 0; |  | ||||||
| 
 |  | ||||||
| 	/* See if there has been given a command line override */ |  | ||||||
| 	if ((reboot_cpu != -1) && (reboot_cpu < nr_cpu_ids) && |  | ||||||
| 		cpu_online(reboot_cpu)) |  | ||||||
| 		reboot_cpu_id = reboot_cpu; |  | ||||||
| 
 |  | ||||||
| 	/* Make certain the cpu I'm about to reboot on is online */ |  | ||||||
| 	if (!cpu_online(reboot_cpu_id)) |  | ||||||
| 		reboot_cpu_id = smp_processor_id(); |  | ||||||
| 
 |  | ||||||
| 	/* Make certain I only run on the appropriate processor */ |  | ||||||
| 	set_cpus_allowed_ptr(current, cpumask_of(reboot_cpu_id)); |  | ||||||
| 
 |  | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * O.K Now that I'm on the appropriate processor, stop all of the | 	 * Stop all of the others. Also disable the local irq to | ||||||
| 	 * others. Also disable the local irq to not receive the per-cpu | 	 * not receive the per-cpu timer interrupt which may trigger | ||||||
| 	 * timer interrupt which may trigger scheduler's load balance. | 	 * scheduler's load balance. | ||||||
| 	 */ | 	 */ | ||||||
| 	local_irq_disable(); | 	local_irq_disable(); | ||||||
| 	stop_other_cpus(); | 	stop_other_cpus(); | ||||||
|  |  | ||||||
|  | @ -17,6 +17,23 @@ enum reboot_mode { | ||||||
| 	REBOOT_SOFT, | 	REBOOT_SOFT, | ||||||
| 	REBOOT_GPIO, | 	REBOOT_GPIO, | ||||||
| }; | }; | ||||||
|  | extern enum reboot_mode reboot_mode; | ||||||
|  | 
 | ||||||
|  | enum reboot_type { | ||||||
|  | 	BOOT_TRIPLE = 't', | ||||||
|  | 	BOOT_KBD = 'k', | ||||||
|  | 	BOOT_BIOS = 'b', | ||||||
|  | 	BOOT_ACPI = 'a', | ||||||
|  | 	BOOT_EFI = 'e', | ||||||
|  | 	BOOT_CF9 = 'p', | ||||||
|  | 	BOOT_CF9_COND = 'q', | ||||||
|  | }; | ||||||
|  | extern enum reboot_type reboot_type; | ||||||
|  | 
 | ||||||
|  | extern int reboot_default; | ||||||
|  | extern int reboot_cpu; | ||||||
|  | extern int reboot_force; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| extern int register_reboot_notifier(struct notifier_block *); | extern int register_reboot_notifier(struct notifier_block *); | ||||||
| extern int unregister_reboot_notifier(struct notifier_block *); | extern int unregister_reboot_notifier(struct notifier_block *); | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| 
 | 
 | ||||||
| #define pr_fmt(fmt)	"reboot: " fmt | #define pr_fmt(fmt)	"reboot: " fmt | ||||||
| 
 | 
 | ||||||
|  | #include <linux/ctype.h> | ||||||
| #include <linux/export.h> | #include <linux/export.h> | ||||||
| #include <linux/kexec.h> | #include <linux/kexec.h> | ||||||
| #include <linux/kmod.h> | #include <linux/kmod.h> | ||||||
|  | @ -24,6 +25,18 @@ int C_A_D = 1; | ||||||
| struct pid *cad_pid; | struct pid *cad_pid; | ||||||
| EXPORT_SYMBOL(cad_pid); | EXPORT_SYMBOL(cad_pid); | ||||||
| 
 | 
 | ||||||
|  | #if defined(CONFIG_ARM) || defined(CONFIG_UNICORE32) | ||||||
|  | #define DEFAULT_REBOOT_MODE		= REBOOT_HARD | ||||||
|  | #else | ||||||
|  | #define DEFAULT_REBOOT_MODE | ||||||
|  | #endif | ||||||
|  | enum reboot_mode reboot_mode DEFAULT_REBOOT_MODE; | ||||||
|  | 
 | ||||||
|  | int reboot_default; | ||||||
|  | int reboot_cpu; | ||||||
|  | enum reboot_type reboot_type = BOOT_ACPI; | ||||||
|  | int reboot_force; | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * If set, this is used for preparing the system to power off. |  * If set, this is used for preparing the system to power off. | ||||||
|  */ |  */ | ||||||
|  | @ -87,7 +100,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier); | ||||||
| static void migrate_to_reboot_cpu(void) | static void migrate_to_reboot_cpu(void) | ||||||
| { | { | ||||||
| 	/* The boot cpu is always logical cpu 0 */ | 	/* The boot cpu is always logical cpu 0 */ | ||||||
| 	int cpu = 0; | 	int cpu = reboot_cpu; | ||||||
| 
 | 
 | ||||||
| 	cpu_hotplug_disable(); | 	cpu_hotplug_disable(); | ||||||
| 
 | 
 | ||||||
|  | @ -343,3 +356,64 @@ int orderly_poweroff(bool force) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| EXPORT_SYMBOL_GPL(orderly_poweroff); | EXPORT_SYMBOL_GPL(orderly_poweroff); | ||||||
|  | 
 | ||||||
|  | static int __init reboot_setup(char *str) | ||||||
|  | { | ||||||
|  | 	for (;;) { | ||||||
|  | 		/*
 | ||||||
|  | 		 * Having anything passed on the command line via | ||||||
|  | 		 * reboot= will cause us to disable DMI checking | ||||||
|  | 		 * below. | ||||||
|  | 		 */ | ||||||
|  | 		reboot_default = 0; | ||||||
|  | 
 | ||||||
|  | 		switch (*str) { | ||||||
|  | 		case 'w': | ||||||
|  | 			reboot_mode = REBOOT_WARM; | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 'c': | ||||||
|  | 			reboot_mode = REBOOT_COLD; | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 'h': | ||||||
|  | 			reboot_mode = REBOOT_HARD; | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 's': | ||||||
|  | 			if (isdigit(*(str+1))) | ||||||
|  | 				reboot_cpu = simple_strtoul(str+1, NULL, 0); | ||||||
|  | 			else if (str[1] == 'm' && str[2] == 'p' && | ||||||
|  | 							isdigit(*(str+3))) | ||||||
|  | 				reboot_cpu = simple_strtoul(str+3, NULL, 0); | ||||||
|  | 			else | ||||||
|  | 				reboot_mode = REBOOT_SOFT; | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 'g': | ||||||
|  | 			reboot_mode = REBOOT_GPIO; | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 'b': | ||||||
|  | 		case 'a': | ||||||
|  | 		case 'k': | ||||||
|  | 		case 't': | ||||||
|  | 		case 'e': | ||||||
|  | 		case 'p': | ||||||
|  | 			reboot_type = *str; | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		case 'f': | ||||||
|  | 			reboot_force = 1; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		str = strchr(str, ','); | ||||||
|  | 		if (str) | ||||||
|  | 			str++; | ||||||
|  | 		else | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  | __setup("reboot=", reboot_setup); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Robin Holt
						Robin Holt