v4.19.13 snapshot.
diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
new file mode 100644
index 0000000..e46a415
--- /dev/null
+++ b/arch/parisc/kernel/ftrace.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Code for tracing calls in Linux kernel.
+ * Copyright (C) 2009-2016 Helge Deller <deller@gmx.de>
+ *
+ * based on code for x86 which is:
+ * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
+ *
+ * future possible enhancements:
+ * 	- add CONFIG_DYNAMIC_FTRACE
+ *	- add CONFIG_STACK_TRACER
+ */
+
+#include <linux/init.h>
+#include <linux/ftrace.h>
+
+#include <asm/assembly.h>
+#include <asm/sections.h>
+#include <asm/ftrace.h>
+
+
+#define __hot __attribute__ ((__section__ (".text.hot")))
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+static void __hot prepare_ftrace_return(unsigned long *parent,
+					unsigned long self_addr)
+{
+	unsigned long old;
+	extern int parisc_return_to_handler;
+
+	if (unlikely(ftrace_graph_is_dead()))
+		return;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return;
+
+	old = *parent;
+
+	if (!function_graph_enter(old, self_addr, 0, NULL))
+		/* activate parisc_return_to_handler() as return point */
+		*parent = (unsigned long) &parisc_return_to_handler;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+void notrace __hot ftrace_function_trampoline(unsigned long parent,
+				unsigned long self_addr,
+				unsigned long org_sp_gr3)
+{
+	extern ftrace_func_t ftrace_trace_function;  /* depends on CONFIG_DYNAMIC_FTRACE */
+	extern int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace);
+
+	if (ftrace_trace_function != ftrace_stub) {
+		/* struct ftrace_ops *op, struct pt_regs *regs); */
+		ftrace_trace_function(parent, self_addr, NULL, NULL);
+		return;
+	}
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	if (ftrace_graph_return != (trace_func_graph_ret_t) ftrace_stub ||
+		ftrace_graph_entry != ftrace_graph_entry_stub) {
+		unsigned long *parent_rp;
+
+		/* calculate pointer to %rp in stack */
+		parent_rp = (unsigned long *) (org_sp_gr3 - RP_OFFSET);
+		/* sanity check: parent_rp should hold parent */
+		if (*parent_rp != parent)
+			return;
+
+		prepare_ftrace_return(parent_rp, self_addr);
+		return;
+	}
+#endif
+}
+