aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_mmiotrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_mmiotrace.c')
-rw-r--r--kernel/trace/trace_mmiotrace.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
new file mode 100644
index 000000000000..e4dd03cc5aa6
--- /dev/null
+++ b/kernel/trace/trace_mmiotrace.c
@@ -0,0 +1,84 @@
1/*
2 * Memory mapped I/O tracing
3 *
4 * Copyright (C) 2008 Pekka Paalanen <pq@iki.fi>
5 */
6
7#define DEBUG 1
8
9#include <linux/kernel.h>
10#include <linux/mmiotrace.h>
11
12#include "trace.h"
13
14extern void
15__trace_special(void *__tr, void *__data,
16 unsigned long arg1, unsigned long arg2, unsigned long arg3);
17
18static struct trace_array *mmio_trace_array;
19
20
21static void mmio_trace_init(struct trace_array *tr)
22{
23 pr_debug("in %s\n", __func__);
24 mmio_trace_array = tr;
25 if (tr->ctrl)
26 enable_mmiotrace();
27}
28
29static void mmio_trace_reset(struct trace_array *tr)
30{
31 pr_debug("in %s\n", __func__);
32 if (tr->ctrl)
33 disable_mmiotrace();
34}
35
36static void mmio_trace_ctrl_update(struct trace_array *tr)
37{
38 pr_debug("in %s\n", __func__);
39 if (tr->ctrl)
40 enable_mmiotrace();
41 else
42 disable_mmiotrace();
43}
44
45static struct tracer mmio_tracer __read_mostly =
46{
47 .name = "mmiotrace",
48 .init = mmio_trace_init,
49 .reset = mmio_trace_reset,
50 .ctrl_update = mmio_trace_ctrl_update,
51};
52
53__init static int init_mmio_trace(void)
54{
55 int ret = init_mmiotrace();
56 if (ret)
57 return ret;
58 return register_tracer(&mmio_tracer);
59}
60device_initcall(init_mmio_trace);
61
62void mmio_trace_record(u32 type, unsigned long addr, unsigned long arg)
63{
64 struct trace_array *tr = mmio_trace_array;
65 struct trace_array_cpu *data = tr->data[smp_processor_id()];
66
67 if (!current || current->pid == 0) {
68 /*
69 * XXX: This is a problem. We need to able to record, no
70 * matter what. tracing_generic_entry_update() would crash.
71 */
72 static unsigned limit;
73 if (limit++ < 12)
74 pr_err("Error in %s: no current.\n", __func__);
75 return;
76 }
77 if (!tr || !data) {
78 static unsigned limit;
79 if (limit++ < 12)
80 pr_err("%s: no tr or data\n", __func__);
81 return;
82 }
83 __trace_special(tr, data, type, addr, arg);
84}