Merge branch 'fix/hda' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[pandora-kernel.git] / arch / sparc / kernel / ftrace.c
index 9103a56..03ab022 100644 (file)
@@ -13,7 +13,7 @@ static const u32 ftrace_nop = 0x01000000;
 
 static u32 ftrace_call_replace(unsigned long ip, unsigned long addr)
 {
-       static u32 call;
+       u32 call;
        s32 off;
 
        off = ((s32)addr - (s32)ip);
@@ -91,3 +91,61 @@ int __init ftrace_dyn_arch_init(void *data)
        return 0;
 }
 #endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+       unsigned long ip = (unsigned long)(&ftrace_graph_call);
+       u32 old, new;
+
+       old = *(u32 *) &ftrace_graph_call;
+       new = ftrace_call_replace(ip, (unsigned long) &ftrace_graph_caller);
+       return ftrace_modify_code(ip, old, new);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+       unsigned long ip = (unsigned long)(&ftrace_graph_call);
+       u32 old, new;
+
+       old = *(u32 *) &ftrace_graph_call;
+       new = ftrace_call_replace(ip, (unsigned long) &ftrace_stub);
+
+       return ftrace_modify_code(ip, old, new);
+}
+
+#endif /* !CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+unsigned long prepare_ftrace_return(unsigned long parent,
+                                   unsigned long self_addr,
+                                   unsigned long frame_pointer)
+{
+       unsigned long return_hooker = (unsigned long) &return_to_handler;
+       struct ftrace_graph_ent trace;
+
+       if (unlikely(atomic_read(&current->tracing_graph_pause)))
+               return parent + 8UL;
+
+       if (ftrace_push_return_trace(parent, self_addr, &trace.depth,
+                                    frame_pointer) == -EBUSY)
+               return parent + 8UL;
+
+       trace.func = self_addr;
+
+       /* Only trace if the calling function expects to */
+       if (!ftrace_graph_entry(&trace)) {
+               current->curr_ret_stack--;
+               return parent + 8UL;
+       }
+
+       return return_hooker;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */