diff options
Diffstat (limited to 'kernel/sys.c')
| -rw-r--r-- | kernel/sys.c | 23 | 
1 files changed, 23 insertions, 0 deletions
| diff --git a/kernel/sys.c b/kernel/sys.c index da24bc1292db..9a24374c23bc 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -16,6 +16,8 @@  #include <linux/init.h>  #include <linux/highuid.h>  #include <linux/fs.h> +#include <linux/kernel.h> +#include <linux/kexec.h>  #include <linux/workqueue.h>  #include <linux/device.h>  #include <linux/key.h> @@ -405,6 +407,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user  	case LINUX_REBOOT_CMD_HALT:  		notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);  		system_state = SYSTEM_HALT; +		device_suspend(PMSG_SUSPEND);  		device_shutdown();  		printk(KERN_EMERG "System halted.\n");  		machine_halt(); @@ -415,6 +418,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user  	case LINUX_REBOOT_CMD_POWER_OFF:  		notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);  		system_state = SYSTEM_POWER_OFF; +		device_suspend(PMSG_SUSPEND);  		device_shutdown();  		printk(KERN_EMERG "Power down.\n");  		machine_power_off(); @@ -431,11 +435,30 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user  		notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);  		system_state = SYSTEM_RESTART; +		device_suspend(PMSG_FREEZE);  		device_shutdown();  		printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);  		machine_restart(buffer);  		break; +#ifdef CONFIG_KEXEC +	case LINUX_REBOOT_CMD_KEXEC: +	{ +		struct kimage *image; +		image = xchg(&kexec_image, 0); +		if (!image) { +			unlock_kernel(); +			return -EINVAL; +		} +		notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); +		system_state = SYSTEM_RESTART; +		device_shutdown(); +		printk(KERN_EMERG "Starting new kernel\n"); +		machine_shutdown(); +		machine_kexec(image); +		break; +	} +#endif  #ifdef CONFIG_SOFTWARE_SUSPEND  	case LINUX_REBOOT_CMD_SW_SUSPEND:  		{ | 
