Merge branch 'dma' into devel
[firefly-linux-kernel-4.4.55.git] / arch / arm / kernel / process.c
index d3ea6fa895212fae625b2c5982ededbd896340fc..af377c73d90bdf2f1fd1ddb34e25b905c1e6f7fa 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/processor.h>
 #include <asm/system.h>
 #include <asm/thread_notify.h>
+#include <asm/stacktrace.h>
 #include <asm/mach/time.h>
 
 static const char *processor_modes[] = {
@@ -372,23 +373,21 @@ EXPORT_SYMBOL(kernel_thread);
 
 unsigned long get_wchan(struct task_struct *p)
 {
-       unsigned long fp, lr;
-       unsigned long stack_start, stack_end;
+       struct stackframe frame;
        int count = 0;
        if (!p || p == current || p->state == TASK_RUNNING)
                return 0;
 
-       stack_start = (unsigned long)end_of_stack(p);
-       stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE;
-
-       fp = thread_saved_fp(p);
+       frame.fp = thread_saved_fp(p);
+       frame.sp = thread_saved_sp(p);
+       frame.lr = 0;                   /* recovered from the stack */
+       frame.pc = thread_saved_pc(p);
        do {
-               if (fp < stack_start || fp > stack_end)
+               int ret = unwind_frame(&frame);
+               if (ret < 0)
                        return 0;
-               lr = ((unsigned long *)fp)[-1];
-               if (!in_sched_functions(lr))
-                       return lr;
-               fp = *(unsigned long *) (fp - 12);
+               if (!in_sched_functions(frame.pc))
+                       return frame.pc;
        } while (count ++ < 16);
        return 0;
 }