aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c109
1 files changed, 67 insertions, 42 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 9a24374c23bc..0bcaed6560ac 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -361,6 +361,64 @@ 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_shutdown();
375 if (!cmd) {
376 printk(KERN_EMERG "Restarting system.\n");
377 } else {
378 printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
379 }
380 printk(".\n");
381 machine_restart(cmd);
382}
383EXPORT_SYMBOL_GPL(kernel_restart);
384
385void kernel_kexec(void)
386{
387#ifdef CONFIG_KEXEC
388 struct kimage *image;
389 image = xchg(&kexec_image, 0);
390 if (!image) {
391 return;
392 }
393 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
394 system_state = SYSTEM_RESTART;
395 device_shutdown();
396 printk(KERN_EMERG "Starting new kernel\n");
397 machine_shutdown();
398 machine_kexec(image);
399#endif
400}
401EXPORT_SYMBOL_GPL(kernel_kexec);
402
403void kernel_halt(void)
404{
405 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
406 system_state = SYSTEM_HALT;
407 device_shutdown();
408 printk(KERN_EMERG "System halted.\n");
409 machine_halt();
410}
411EXPORT_SYMBOL_GPL(kernel_halt);
412
413void kernel_power_off(void)
414{
415 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
416 system_state = SYSTEM_POWER_OFF;
417 device_shutdown();
418 printk(KERN_EMERG "Power down.\n");
419 machine_power_off();
420}
421EXPORT_SYMBOL_GPL(kernel_power_off);
364 422
365/* 423/*
366 * Reboot system call: for obvious reasons only root may call it, 424 * Reboot system call: for obvious reasons only root may call it,
@@ -389,11 +447,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
389 lock_kernel(); 447 lock_kernel();
390 switch (cmd) { 448 switch (cmd) {
391 case LINUX_REBOOT_CMD_RESTART: 449 case LINUX_REBOOT_CMD_RESTART:
392 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); 450 kernel_restart(NULL);
393 system_state = SYSTEM_RESTART;
394 device_shutdown();
395 printk(KERN_EMERG "Restarting system.\n");
396 machine_restart(NULL);
397 break; 451 break;
398 452
399 case LINUX_REBOOT_CMD_CAD_ON: 453 case LINUX_REBOOT_CMD_CAD_ON:
@@ -405,23 +459,13 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
405 break; 459 break;
406 460
407 case LINUX_REBOOT_CMD_HALT: 461 case LINUX_REBOOT_CMD_HALT:
408 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); 462 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(); 463 unlock_kernel();
415 do_exit(0); 464 do_exit(0);
416 break; 465 break;
417 466
418 case LINUX_REBOOT_CMD_POWER_OFF: 467 case LINUX_REBOOT_CMD_POWER_OFF:
419 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); 468 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(); 469 unlock_kernel();
426 do_exit(0); 470 do_exit(0);
427 break; 471 break;
@@ -433,32 +477,14 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
433 } 477 }
434 buffer[sizeof(buffer) - 1] = '\0'; 478 buffer[sizeof(buffer) - 1] = '\0';
435 479
436 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer); 480 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; 481 break;
443 482
444#ifdef CONFIG_KEXEC
445 case LINUX_REBOOT_CMD_KEXEC: 483 case LINUX_REBOOT_CMD_KEXEC:
446 { 484 kernel_kexec();
447 struct kimage *image; 485 unlock_kernel();
448 image = xchg(&kexec_image, 0); 486 return -EINVAL;
449 if (!image) { 487
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 488#ifdef CONFIG_SOFTWARE_SUSPEND
463 case LINUX_REBOOT_CMD_SW_SUSPEND: 489 case LINUX_REBOOT_CMD_SW_SUSPEND:
464 { 490 {
@@ -478,8 +504,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
478 504
479static void deferred_cad(void *dummy) 505static void deferred_cad(void *dummy)
480{ 506{
481 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); 507 kernel_restart(NULL);
482 machine_restart(NULL);
483} 508}
484 509
485/* 510/*