aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/power/Kconfig2
-rw-r--r--kernel/power/disk.c6
-rw-r--r--kernel/power/power.h2
-rw-r--r--kernel/power/swsusp.c12
-rw-r--r--kernel/printk.c7
-rw-r--r--kernel/signal.c31
-rw-r--r--kernel/sys.c52
7 files changed, 78 insertions, 34 deletions
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 396c7873e804..46a5e5acff97 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -29,7 +29,7 @@ config PM_DEBUG
29 29
30config SOFTWARE_SUSPEND 30config SOFTWARE_SUSPEND
31 bool "Software Suspend" 31 bool "Software Suspend"
32 depends on PM && SWAP && (X86 || ((FVR || PPC32) && !SMP)) 32 depends on PM && SWAP && (X86 && (!SMP || SUSPEND_SMP)) || ((FVR || PPC32) && !SMP)
33 ---help--- 33 ---help---
34 Enable the possibility of suspending the machine. 34 Enable the possibility of suspending the machine.
35 It doesn't need APM. 35 It doesn't need APM.
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 2d8bf054d036..761956e813f5 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -17,12 +17,12 @@
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/fs.h> 18#include <linux/fs.h>
19#include <linux/mount.h> 19#include <linux/mount.h>
20#include <linux/pm.h>
20 21
21#include "power.h" 22#include "power.h"
22 23
23 24
24extern suspend_disk_method_t pm_disk_mode; 25extern suspend_disk_method_t pm_disk_mode;
25extern struct pm_ops * pm_ops;
26 26
27extern int swsusp_suspend(void); 27extern int swsusp_suspend(void);
28extern int swsusp_write(void); 28extern int swsusp_write(void);
@@ -49,13 +49,11 @@ dev_t swsusp_resume_device;
49 49
50static void power_down(suspend_disk_method_t mode) 50static void power_down(suspend_disk_method_t mode)
51{ 51{
52 unsigned long flags;
53 int error = 0; 52 int error = 0;
54 53
55 local_irq_save(flags);
56 switch(mode) { 54 switch(mode) {
57 case PM_DISK_PLATFORM: 55 case PM_DISK_PLATFORM:
58 device_shutdown(); 56 kernel_power_off_prepare();
59 error = pm_ops->enter(PM_SUSPEND_DISK); 57 error = pm_ops->enter(PM_SUSPEND_DISK);
60 break; 58 break;
61 case PM_DISK_SHUTDOWN: 59 case PM_DISK_SHUTDOWN:
diff --git a/kernel/power/power.h b/kernel/power/power.h
index cd6a3493cc0d..9c9167d910dd 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -1,7 +1,7 @@
1#include <linux/suspend.h> 1#include <linux/suspend.h>
2#include <linux/utsname.h> 2#include <linux/utsname.h>
3 3
4/* With SUSPEND_CONSOLE defined, it suspend looks *really* cool, but 4/* With SUSPEND_CONSOLE defined suspend looks *really* cool, but
5 we probably do not take enough locks for switching consoles, etc, 5 we probably do not take enough locks for switching consoles, etc,
6 so bad things might happen. 6 so bad things might happen.
7*/ 7*/
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index d967e875ee82..1cc9ff25e479 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -363,7 +363,7 @@ static void lock_swapdevices(void)
363} 363}
364 364
365/** 365/**
366 * write_swap_page - Write one page to a fresh swap location. 366 * write_page - Write one page to a fresh swap location.
367 * @addr: Address we're writing. 367 * @addr: Address we're writing.
368 * @loc: Place to store the entry we used. 368 * @loc: Place to store the entry we used.
369 * 369 *
@@ -863,6 +863,9 @@ static int alloc_image_pages(void)
863 return 0; 863 return 0;
864} 864}
865 865
866/* Free pages we allocated for suspend. Suspend pages are alocated
867 * before atomic copy, so we need to free them after resume.
868 */
866void swsusp_free(void) 869void swsusp_free(void)
867{ 870{
868 BUG_ON(PageNosave(virt_to_page(pagedir_save))); 871 BUG_ON(PageNosave(virt_to_page(pagedir_save)));
@@ -918,6 +921,7 @@ static int swsusp_alloc(void)
918 921
919 pagedir_nosave = NULL; 922 pagedir_nosave = NULL;
920 nr_copy_pages = calc_nr(nr_copy_pages); 923 nr_copy_pages = calc_nr(nr_copy_pages);
924 nr_copy_pages_check = nr_copy_pages;
921 925
922 pr_debug("suspend: (pages needed: %d + %d free: %d)\n", 926 pr_debug("suspend: (pages needed: %d + %d free: %d)\n",
923 nr_copy_pages, PAGES_FOR_IO, nr_free_pages()); 927 nr_copy_pages, PAGES_FOR_IO, nr_free_pages());
@@ -940,7 +944,6 @@ static int swsusp_alloc(void)
940 return error; 944 return error;
941 } 945 }
942 946
943 nr_copy_pages_check = nr_copy_pages;
944 return 0; 947 return 0;
945} 948}
946 949
@@ -1213,8 +1216,9 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
1213 free_pagedir(pblist); 1216 free_pagedir(pblist);
1214 free_eaten_memory(); 1217 free_eaten_memory();
1215 pblist = NULL; 1218 pblist = NULL;
1216 } 1219 /* Is this even worth handling? It should never ever happen, and we
1217 else 1220 have just lost user's state, anyway... */
1221 } else
1218 printk("swsusp: Relocated %d pages\n", rel); 1222 printk("swsusp: Relocated %d pages\n", rel);
1219 1223
1220 return pblist; 1224 return pblist;
diff --git a/kernel/printk.c b/kernel/printk.c
index a967605bc2e3..4b8f0f9230a4 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -488,6 +488,11 @@ static int __init printk_time_setup(char *str)
488 488
489__setup("time", printk_time_setup); 489__setup("time", printk_time_setup);
490 490
491__attribute__((weak)) unsigned long long printk_clock(void)
492{
493 return sched_clock();
494}
495
491/* 496/*
492 * This is printk. It can be called from any context. We want it to work. 497 * This is printk. It can be called from any context. We want it to work.
493 * 498 *
@@ -565,7 +570,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
565 loglev_char = default_message_loglevel 570 loglev_char = default_message_loglevel
566 + '0'; 571 + '0';
567 } 572 }
568 t = sched_clock(); 573 t = printk_clock();
569 nanosec_rem = do_div(t, 1000000000); 574 nanosec_rem = do_div(t, 1000000000);
570 tlen = sprintf(tbuf, 575 tlen = sprintf(tbuf,
571 "<%c>[%5lu.%06lu] ", 576 "<%c>[%5lu.%06lu] ",
diff --git a/kernel/signal.c b/kernel/signal.c
index b92c3c9f8b9a..5a274705ba19 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -936,34 +936,31 @@ force_sig_specific(int sig, struct task_struct *t)
936 * as soon as they're available, so putting the signal on the shared queue 936 * as soon as they're available, so putting the signal on the shared queue
937 * will be equivalent to sending it to one such thread. 937 * will be equivalent to sending it to one such thread.
938 */ 938 */
939#define wants_signal(sig, p, mask) \ 939static inline int wants_signal(int sig, struct task_struct *p)
940 (!sigismember(&(p)->blocked, sig) \ 940{
941 && !((p)->state & mask) \ 941 if (sigismember(&p->blocked, sig))
942 && !((p)->flags & PF_EXITING) \ 942 return 0;
943 && (task_curr(p) || !signal_pending(p))) 943 if (p->flags & PF_EXITING)
944 944 return 0;
945 if (sig == SIGKILL)
946 return 1;
947 if (p->state & (TASK_STOPPED | TASK_TRACED))
948 return 0;
949 return task_curr(p) || !signal_pending(p);
950}
945 951
946static void 952static void
947__group_complete_signal(int sig, struct task_struct *p) 953__group_complete_signal(int sig, struct task_struct *p)
948{ 954{
949 unsigned int mask;
950 struct task_struct *t; 955 struct task_struct *t;
951 956
952 /* 957 /*
953 * Don't bother traced and stopped tasks (but
954 * SIGKILL will punch through that).
955 */
956 mask = TASK_STOPPED | TASK_TRACED;
957 if (sig == SIGKILL)
958 mask = 0;
959
960 /*
961 * Now find a thread we can wake up to take the signal off the queue. 958 * Now find a thread we can wake up to take the signal off the queue.
962 * 959 *
963 * If the main thread wants the signal, it gets first crack. 960 * If the main thread wants the signal, it gets first crack.
964 * Probably the least surprising to the average bear. 961 * Probably the least surprising to the average bear.
965 */ 962 */
966 if (wants_signal(sig, p, mask)) 963 if (wants_signal(sig, p))
967 t = p; 964 t = p;
968 else if (thread_group_empty(p)) 965 else if (thread_group_empty(p))
969 /* 966 /*
@@ -981,7 +978,7 @@ __group_complete_signal(int sig, struct task_struct *p)
981 t = p->signal->curr_target = p; 978 t = p->signal->curr_target = p;
982 BUG_ON(t->tgid != p->tgid); 979 BUG_ON(t->tgid != p->tgid);
983 980
984 while (!wants_signal(sig, t, mask)) { 981 while (!wants_signal(sig, t)) {
985 t = next_thread(t); 982 t = next_thread(t);
986 if (t == p->signal->curr_target) 983 if (t == p->signal->curr_target)
987 /* 984 /*
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 */
364void emergency_restart(void) 372void emergency_restart(void)
365{ 373{
366 machine_emergency_restart(); 374 machine_emergency_restart();
367} 375}
368EXPORT_SYMBOL_GPL(emergency_restart); 376EXPORT_SYMBOL_GPL(emergency_restart);
369 377
370void 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 */
384void 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}
390void 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}
383EXPORT_SYMBOL_GPL(kernel_restart); 401EXPORT_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 */
385void kernel_kexec(void) 409void 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}
401EXPORT_SYMBOL_GPL(kernel_kexec); 423EXPORT_SYMBOL_GPL(kernel_kexec);
402 424
403void kernel_halt(void) 425/**
426 * kernel_halt - halt the system
427 *
428 * Shutdown everything and perform a clean system halt.
429 */
430void 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}
436void 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}
411EXPORT_SYMBOL_GPL(kernel_halt); 442EXPORT_SYMBOL_GPL(kernel_halt);
412 443
413void 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 */
449void 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}
455void 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}