aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c113
1 files changed, 71 insertions, 42 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 9a24374c23bc..a74039036fb4 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -361,6 +361,68 @@ out_unlock:
361 return retval; 361 return retval;
362} 362}
363 363
364void emergency_restart(void)
365{
366 machine_emergency_restart();
367}
368EXPORT_SYMBOL_GPL(emergency_restart);
369
370void kernel_restart(char *cmd)
371{
372 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
373 system_state = SYSTEM_RESTART;
374 device_suspend(PMSG_FREEZE);
375 device_shutdown();
376 if (!cmd) {
377 printk(KERN_EMERG "Restarting system.\n");
378 } else {
379 printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
380 }
381 printk(".\n");
382 machine_restart(cmd);
383}
384EXPORT_SYMBOL_GPL(kernel_restart);
385
386void kernel_kexec(void)
387{
388#ifdef CONFIG_KEXEC
389 struct kimage *image;
390 image = xchg(&kexec_image, 0);
391 if (!image) {
392 return;
393 }
394 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
395 system_state = SYSTEM_RESTART;
396 device_suspend(PMSG_FREEZE);
397 device_shutdown();
398 printk(KERN_EMERG "Starting new kernel\n");
399 machine_shutdown();
400 machine_kexec(image);
401#endif
402}
403EXPORT_SYMBOL_GPL(kernel_kexec);
404
405void kernel_halt(void)
406{
407 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
408 system_state = SYSTEM_HALT;
409 device_suspend(PMSG_SUSPEND);
410 device_shutdown();
411 printk(KERN_EMERG "System halted.\n");
412 machine_halt();
413}
414EXPORT_SYMBOL_GPL(kernel_halt);
415
416void kernel_power_off(void)
417{
418 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
419 system_state = SYSTEM_POWER_OFF;
420 device_suspend(PMSG_SUSPEND);
421 device_shutdown();
422 printk(KERN_EMERG "Power down.\n");
423 machine_power_off();
424}
425EXPORT_SYMBOL_GPL(kernel_power_off);
364 426
365/* 427/*
366 * Reboot system call: for obvious reasons only root may call it, 428 * Reboot system call: for obvious reasons only root may call it,
@@ -389,11 +451,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
389 lock_kernel(); 451 lock_kernel();
390 switch (cmd) { 452 switch (cmd) {
391 case LINUX_REBOOT_CMD_RESTART: 453 case LINUX_REBOOT_CMD_RESTART:
392 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); 454 kernel_restart(NULL);
393 system_state = SYSTEM_RESTART;
394 device_shutdown();
395 printk(KERN_EMERG "Restarting system.\n");
396 machine_restart(NULL);
397 break; 455 break;
398 456
399 case LINUX_REBOOT_CMD_CAD_ON: 457 case LINUX_REBOOT_CMD_CAD_ON:
@@ -405,23 +463,13 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
405 break; 463 break;
406 464
407 case LINUX_REBOOT_CMD_HALT: 465 case LINUX_REBOOT_CMD_HALT:
408 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); 466 kernel_halt();
409 system_state = SYSTEM_HALT;
410 device_suspend(PMSG_SUSPEND);
411 device_shutdown();
412 printk(KERN_EMERG "System halted.\n");
413 machine_halt();
414 unlock_kernel(); 467 unlock_kernel();
415 do_exit(0); 468 do_exit(0);
416 break; 469 break;
417 470
418 case LINUX_REBOOT_CMD_POWER_OFF: 471 case LINUX_REBOOT_CMD_POWER_OFF:
419 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); 472 kernel_power_off();
420 system_state = SYSTEM_POWER_OFF;
421 device_suspend(PMSG_SUSPEND);
422 device_shutdown();
423 printk(KERN_EMERG "Power down.\n");
424 machine_power_off();
425 unlock_kernel(); 473 unlock_kernel();
426 do_exit(0); 474 do_exit(0);
427 break; 475 break;
@@ -433,32 +481,14 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
433 } 481 }
434 buffer[sizeof(buffer) - 1] = '\0'; 482 buffer[sizeof(buffer) - 1] = '\0';
435 483
436 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer); 484 kernel_restart(buffer);
437 system_state = SYSTEM_RESTART;
438 device_suspend(PMSG_FREEZE);
439 device_shutdown();
440 printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
441 machine_restart(buffer);
442 break; 485 break;
443 486
444#ifdef CONFIG_KEXEC
445 case LINUX_REBOOT_CMD_KEXEC: 487 case LINUX_REBOOT_CMD_KEXEC:
446 { 488 kernel_kexec();
447 struct kimage *image; 489 unlock_kernel();
448 image = xchg(&kexec_image, 0); 490 return -EINVAL;
449 if (!image) { 491
450 unlock_kernel();
451 return -EINVAL;
452 }
453 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
454 system_state = SYSTEM_RESTART;
455 device_shutdown();
456 printk(KERN_EMERG "Starting new kernel\n");
457 machine_shutdown();
458 machine_kexec(image);
459 break;
460 }
461#endif
462#ifdef CONFIG_SOFTWARE_SUSPEND 492#ifdef CONFIG_SOFTWARE_SUSPEND
463 case LINUX_REBOOT_CMD_SW_SUSPEND: 493 case LINUX_REBOOT_CMD_SW_SUSPEND:
464 { 494 {
@@ -478,8 +508,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
478 508
479static void deferred_cad(void *dummy) 509static void deferred_cad(void *dummy)
480{ 510{
481 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); 511 kernel_restart(NULL);
482 machine_restart(NULL);
483} 512}
484 513
485/* 514/*