diff options
-rw-r--r-- | include/linux/reboot.h | 4 | ||||
-rw-r--r-- | kernel/sys.c | 52 |
2 files changed, 50 insertions, 6 deletions
diff --git a/include/linux/reboot.h b/include/linux/reboot.h index 3b3266ff1a95..7ab2cdb83ef0 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h | |||
@@ -59,6 +59,10 @@ extern void machine_crash_shutdown(struct pt_regs *); | |||
59 | * Architecture independent implemenations of sys_reboot commands. | 59 | * Architecture independent implemenations of sys_reboot commands. |
60 | */ | 60 | */ |
61 | 61 | ||
62 | extern void kernel_restart_prepare(char *cmd); | ||
63 | extern void kernel_halt_prepare(void); | ||
64 | extern void kernel_power_off_prepare(void); | ||
65 | |||
62 | extern void kernel_restart(char *cmd); | 66 | extern void kernel_restart(char *cmd); |
63 | extern void kernel_halt(void); | 67 | extern void kernel_halt(void); |
64 | extern void kernel_power_off(void); | 68 | extern void kernel_power_off(void); |
diff --git a/kernel/sys.c b/kernel/sys.c index f723522e6986..2fa1ed18123c 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -361,17 +361,35 @@ out_unlock: | |||
361 | return retval; | 361 | return retval; |
362 | } | 362 | } |
363 | 363 | ||
364 | /** | ||
365 | * emergency_restart - reboot the system | ||
366 | * | ||
367 | * Without shutting down any hardware or taking any locks | ||
368 | * reboot the system. This is called when we know we are in | ||
369 | * trouble so this is our best effort to reboot. This is | ||
370 | * safe to call in interrupt context. | ||
371 | */ | ||
364 | void emergency_restart(void) | 372 | void emergency_restart(void) |
365 | { | 373 | { |
366 | machine_emergency_restart(); | 374 | machine_emergency_restart(); |
367 | } | 375 | } |
368 | EXPORT_SYMBOL_GPL(emergency_restart); | 376 | EXPORT_SYMBOL_GPL(emergency_restart); |
369 | 377 | ||
370 | void kernel_restart(char *cmd) | 378 | /** |
379 | * kernel_restart - reboot the system | ||
380 | * | ||
381 | * Shutdown everything and perform a clean reboot. | ||
382 | * This is not safe to call in interrupt context. | ||
383 | */ | ||
384 | void kernel_restart_prepare(char *cmd) | ||
371 | { | 385 | { |
372 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); | 386 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); |
373 | system_state = SYSTEM_RESTART; | 387 | system_state = SYSTEM_RESTART; |
374 | device_shutdown(); | 388 | device_shutdown(); |
389 | } | ||
390 | void kernel_restart(char *cmd) | ||
391 | { | ||
392 | kernel_restart_prepare(cmd); | ||
375 | if (!cmd) { | 393 | if (!cmd) { |
376 | printk(KERN_EMERG "Restarting system.\n"); | 394 | printk(KERN_EMERG "Restarting system.\n"); |
377 | } else { | 395 | } else { |
@@ -382,6 +400,12 @@ void kernel_restart(char *cmd) | |||
382 | } | 400 | } |
383 | EXPORT_SYMBOL_GPL(kernel_restart); | 401 | EXPORT_SYMBOL_GPL(kernel_restart); |
384 | 402 | ||
403 | /** | ||
404 | * kernel_kexec - reboot the system | ||
405 | * | ||
406 | * Move into place and start executing a preloaded standalone | ||
407 | * executable. If nothing was preloaded return an error. | ||
408 | */ | ||
385 | void kernel_kexec(void) | 409 | void kernel_kexec(void) |
386 | { | 410 | { |
387 | #ifdef CONFIG_KEXEC | 411 | #ifdef CONFIG_KEXEC |
@@ -390,9 +414,7 @@ void kernel_kexec(void) | |||
390 | if (!image) { | 414 | if (!image) { |
391 | return; | 415 | return; |
392 | } | 416 | } |
393 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); | 417 | kernel_restart_prepare(NULL); |
394 | system_state = SYSTEM_RESTART; | ||
395 | device_shutdown(); | ||
396 | printk(KERN_EMERG "Starting new kernel\n"); | 418 | printk(KERN_EMERG "Starting new kernel\n"); |
397 | machine_shutdown(); | 419 | machine_shutdown(); |
398 | machine_kexec(image); | 420 | machine_kexec(image); |
@@ -400,21 +422,39 @@ void kernel_kexec(void) | |||
400 | } | 422 | } |
401 | EXPORT_SYMBOL_GPL(kernel_kexec); | 423 | EXPORT_SYMBOL_GPL(kernel_kexec); |
402 | 424 | ||
403 | void kernel_halt(void) | 425 | /** |
426 | * kernel_halt - halt the system | ||
427 | * | ||
428 | * Shutdown everything and perform a clean system halt. | ||
429 | */ | ||
430 | void kernel_halt_prepare(void) | ||
404 | { | 431 | { |
405 | notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); | 432 | notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); |
406 | system_state = SYSTEM_HALT; | 433 | system_state = SYSTEM_HALT; |
407 | device_shutdown(); | 434 | device_shutdown(); |
435 | } | ||
436 | void kernel_halt(void) | ||
437 | { | ||
438 | kernel_halt_prepare(); | ||
408 | printk(KERN_EMERG "System halted.\n"); | 439 | printk(KERN_EMERG "System halted.\n"); |
409 | machine_halt(); | 440 | machine_halt(); |
410 | } | 441 | } |
411 | EXPORT_SYMBOL_GPL(kernel_halt); | 442 | EXPORT_SYMBOL_GPL(kernel_halt); |
412 | 443 | ||
413 | void kernel_power_off(void) | 444 | /** |
445 | * kernel_power_off - power_off the system | ||
446 | * | ||
447 | * Shutdown everything and perform a clean system power_off. | ||
448 | */ | ||
449 | void kernel_power_off_prepare(void) | ||
414 | { | 450 | { |
415 | notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); | 451 | notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); |
416 | system_state = SYSTEM_POWER_OFF; | 452 | system_state = SYSTEM_POWER_OFF; |
417 | device_shutdown(); | 453 | device_shutdown(); |
454 | } | ||
455 | void kernel_power_off(void) | ||
456 | { | ||
457 | kernel_power_off_prepare(); | ||
418 | printk(KERN_EMERG "Power down.\n"); | 458 | printk(KERN_EMERG "Power down.\n"); |
419 | machine_power_off(); | 459 | machine_power_off(); |
420 | } | 460 | } |