aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/reboot.h9
-rw-r--r--kernel/sys.c106
2 files changed, 73 insertions, 42 deletions
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 2d4dd23168dd..828ba4f107d9 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -55,6 +55,15 @@ extern void machine_shutdown(void);
55struct pt_regs; 55struct pt_regs;
56extern void machine_crash_shutdown(struct pt_regs *); 56extern void machine_crash_shutdown(struct pt_regs *);
57 57
58/*
59 * Architecture independent implemenations of sys_reboot commands.
60 */
61
62extern void kernel_restart(char *cmd);
63extern void kernel_halt(void);
64extern void kernel_power_off(void);
65extern void kernel_kexec(void);
66
58#endif 67#endif
59 68
60#endif /* _LINUX_REBOOT_H */ 69#endif /* _LINUX_REBOOT_H */
diff --git a/kernel/sys.c b/kernel/sys.c
index 5fc10d3e3891..7e033809ef5f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -361,6 +361,62 @@ out_unlock:
361 return retval; 361 return retval;
362} 362}
363 363
364void kernel_restart(char *cmd)
365{
366 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
367 system_state = SYSTEM_RESTART;
368 device_suspend(PMSG_FREEZE);
369 device_shutdown();
370 if (!cmd) {
371 printk(KERN_EMERG "Restarting system.\n");
372 } else {
373 printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
374 }
375 printk(".\n");
376 machine_restart(cmd);
377}
378EXPORT_SYMBOL_GPL(kernel_restart);
379
380void kernel_kexec(void)
381{
382#ifdef CONFIG_KEXEC
383 struct kimage *image;
384 image = xchg(&kexec_image, 0);
385 if (!image) {
386 return;
387 }
388 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
389 system_state = SYSTEM_RESTART;
390 device_suspend(PMSG_FREEZE);
391 device_shutdown();
392 printk(KERN_EMERG "Starting new kernel\n");
393 machine_shutdown();
394 machine_kexec(image);
395#endif
396}
397EXPORT_SYMBOL_GPL(kernel_kexec);
398
399void kernel_halt(void)
400{
401 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
402 system_state = SYSTEM_HALT;
403 device_suspend(PMSG_SUSPEND);
404 device_shutdown();
405 printk(KERN_EMERG "System halted.\n");
406 machine_halt();
407}
408EXPORT_SYMBOL_GPL(kernel_halt);
409
410void kernel_power_off(void)
411{
412 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
413 system_state = SYSTEM_POWER_OFF;
414 device_suspend(PMSG_SUSPEND);
415 device_shutdown();
416 printk(KERN_EMERG "Power down.\n");
417 machine_power_off();
418}
419EXPORT_SYMBOL_GPL(kernel_power_off);
364 420
365/* 421/*
366 * Reboot system call: for obvious reasons only root may call it, 422 * Reboot system call: for obvious reasons only root may call it,
@@ -389,12 +445,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
389 lock_kernel(); 445 lock_kernel();
390 switch (cmd) { 446 switch (cmd) {
391 case LINUX_REBOOT_CMD_RESTART: 447 case LINUX_REBOOT_CMD_RESTART:
392 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); 448 kernel_restart(NULL);
393 system_state = SYSTEM_RESTART;
394 device_suspend(PMSG_FREEZE);
395 device_shutdown();
396 printk(KERN_EMERG "Restarting system.\n");
397 machine_restart(NULL);
398 break; 449 break;
399 450
400 case LINUX_REBOOT_CMD_CAD_ON: 451 case LINUX_REBOOT_CMD_CAD_ON:
@@ -406,23 +457,13 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
406 break; 457 break;
407 458
408 case LINUX_REBOOT_CMD_HALT: 459 case LINUX_REBOOT_CMD_HALT:
409 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); 460 kernel_halt();
410 system_state = SYSTEM_HALT;
411 device_suspend(PMSG_SUSPEND);
412 device_shutdown();
413 printk(KERN_EMERG "System halted.\n");
414 machine_halt();
415 unlock_kernel(); 461 unlock_kernel();
416 do_exit(0); 462 do_exit(0);
417 break; 463 break;
418 464
419 case LINUX_REBOOT_CMD_POWER_OFF: 465 case LINUX_REBOOT_CMD_POWER_OFF:
420 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); 466 kernel_power_off();
421 system_state = SYSTEM_POWER_OFF;
422 device_suspend(PMSG_SUSPEND);
423 device_shutdown();
424 printk(KERN_EMERG "Power down.\n");
425 machine_power_off();
426 unlock_kernel(); 467 unlock_kernel();
427 do_exit(0); 468 do_exit(0);
428 break; 469 break;
@@ -434,33 +475,14 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
434 } 475 }
435 buffer[sizeof(buffer) - 1] = '\0'; 476 buffer[sizeof(buffer) - 1] = '\0';
436 477
437 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer); 478 kernel_restart(buffer);
438 system_state = SYSTEM_RESTART;
439 device_suspend(PMSG_FREEZE);
440 device_shutdown();
441 printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
442 machine_restart(buffer);
443 break; 479 break;
444 480
445#ifdef CONFIG_KEXEC
446 case LINUX_REBOOT_CMD_KEXEC: 481 case LINUX_REBOOT_CMD_KEXEC:
447 { 482 kernel_kexec();
448 struct kimage *image; 483 unlock_kernel();
449 image = xchg(&kexec_image, 0); 484 return -EINVAL;
450 if (!image) { 485
451 unlock_kernel();
452 return -EINVAL;
453 }
454 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
455 system_state = SYSTEM_RESTART;
456 device_suspend(PMSG_FREEZE);
457 device_shutdown();
458 printk(KERN_EMERG "Starting new kernel\n");
459 machine_shutdown();
460 machine_kexec(image);
461 break;
462 }
463#endif
464#ifdef CONFIG_SOFTWARE_SUSPEND 486#ifdef CONFIG_SOFTWARE_SUSPEND
465 case LINUX_REBOOT_CMD_SW_SUSPEND: 487 case LINUX_REBOOT_CMD_SW_SUSPEND:
466 { 488 {