diff options
Diffstat (limited to 'arch/arm/kernel/process.c')
-rw-r--r-- | arch/arm/kernel/process.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index d3ea6fa89521..2de14e2afdc5 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/processor.h> | 34 | #include <asm/processor.h> |
35 | #include <asm/system.h> | 35 | #include <asm/system.h> |
36 | #include <asm/thread_notify.h> | 36 | #include <asm/thread_notify.h> |
37 | #include <asm/stacktrace.h> | ||
37 | #include <asm/mach/time.h> | 38 | #include <asm/mach/time.h> |
38 | 39 | ||
39 | static const char *processor_modes[] = { | 40 | static const char *processor_modes[] = { |
@@ -82,7 +83,7 @@ static int __init hlt_setup(char *__unused) | |||
82 | __setup("nohlt", nohlt_setup); | 83 | __setup("nohlt", nohlt_setup); |
83 | __setup("hlt", hlt_setup); | 84 | __setup("hlt", hlt_setup); |
84 | 85 | ||
85 | void arm_machine_restart(char mode) | 86 | void arm_machine_restart(char mode, const char *cmd) |
86 | { | 87 | { |
87 | /* | 88 | /* |
88 | * Clean and disable cache, and turn off interrupts | 89 | * Clean and disable cache, and turn off interrupts |
@@ -99,7 +100,7 @@ void arm_machine_restart(char mode) | |||
99 | /* | 100 | /* |
100 | * Now call the architecture specific reboot code. | 101 | * Now call the architecture specific reboot code. |
101 | */ | 102 | */ |
102 | arch_reset(mode); | 103 | arch_reset(mode, cmd); |
103 | 104 | ||
104 | /* | 105 | /* |
105 | * Whoops - the architecture was unable to reboot. | 106 | * Whoops - the architecture was unable to reboot. |
@@ -119,7 +120,7 @@ EXPORT_SYMBOL(pm_idle); | |||
119 | void (*pm_power_off)(void); | 120 | void (*pm_power_off)(void); |
120 | EXPORT_SYMBOL(pm_power_off); | 121 | EXPORT_SYMBOL(pm_power_off); |
121 | 122 | ||
122 | void (*arm_pm_restart)(char str) = arm_machine_restart; | 123 | void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart; |
123 | EXPORT_SYMBOL_GPL(arm_pm_restart); | 124 | EXPORT_SYMBOL_GPL(arm_pm_restart); |
124 | 125 | ||
125 | 126 | ||
@@ -194,9 +195,9 @@ void machine_power_off(void) | |||
194 | pm_power_off(); | 195 | pm_power_off(); |
195 | } | 196 | } |
196 | 197 | ||
197 | void machine_restart(char * __unused) | 198 | void machine_restart(char *cmd) |
198 | { | 199 | { |
199 | arm_pm_restart(reboot_mode); | 200 | arm_pm_restart(reboot_mode, cmd); |
200 | } | 201 | } |
201 | 202 | ||
202 | void __show_regs(struct pt_regs *regs) | 203 | void __show_regs(struct pt_regs *regs) |
@@ -372,23 +373,21 @@ EXPORT_SYMBOL(kernel_thread); | |||
372 | 373 | ||
373 | unsigned long get_wchan(struct task_struct *p) | 374 | unsigned long get_wchan(struct task_struct *p) |
374 | { | 375 | { |
375 | unsigned long fp, lr; | 376 | struct stackframe frame; |
376 | unsigned long stack_start, stack_end; | ||
377 | int count = 0; | 377 | int count = 0; |
378 | if (!p || p == current || p->state == TASK_RUNNING) | 378 | if (!p || p == current || p->state == TASK_RUNNING) |
379 | return 0; | 379 | return 0; |
380 | 380 | ||
381 | stack_start = (unsigned long)end_of_stack(p); | 381 | frame.fp = thread_saved_fp(p); |
382 | stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE; | 382 | frame.sp = thread_saved_sp(p); |
383 | 383 | frame.lr = 0; /* recovered from the stack */ | |
384 | fp = thread_saved_fp(p); | 384 | frame.pc = thread_saved_pc(p); |
385 | do { | 385 | do { |
386 | if (fp < stack_start || fp > stack_end) | 386 | int ret = unwind_frame(&frame); |
387 | if (ret < 0) | ||
387 | return 0; | 388 | return 0; |
388 | lr = ((unsigned long *)fp)[-1]; | 389 | if (!in_sched_functions(frame.pc)) |
389 | if (!in_sched_functions(lr)) | 390 | return frame.pc; |
390 | return lr; | ||
391 | fp = *(unsigned long *) (fp - 12); | ||
392 | } while (count ++ < 16); | 391 | } while (count ++ < 16); |
393 | return 0; | 392 | return 0; |
394 | } | 393 | } |