1f984b51eSPekka Paalanen /* 2f984b51eSPekka Paalanen * Memory mapped I/O tracing 3f984b51eSPekka Paalanen * 4f984b51eSPekka Paalanen * Copyright (C) 2008 Pekka Paalanen <pq@iki.fi> 5f984b51eSPekka Paalanen */ 6f984b51eSPekka Paalanen 7f984b51eSPekka Paalanen #define DEBUG 1 8f984b51eSPekka Paalanen 9f984b51eSPekka Paalanen #include <linux/kernel.h> 10f984b51eSPekka Paalanen #include <linux/mmiotrace.h> 1113829537SPekka Paalanen #include <linux/pci.h> 12*5a0e3ad6STejun Heo #include <linux/slab.h> 13a5dec557SLi Zefan #include <linux/time.h> 14a5dec557SLi Zefan 15173ed24eSPekka Paalanen #include <asm/atomic.h> 16f984b51eSPekka Paalanen 17f984b51eSPekka Paalanen #include "trace.h" 18f0868d1eSSteven Rostedt #include "trace_output.h" 19f984b51eSPekka Paalanen 20d0a7e8caSPekka Paalanen struct header_iter { 21d0a7e8caSPekka Paalanen struct pci_dev *dev; 22d0a7e8caSPekka Paalanen }; 23d0a7e8caSPekka Paalanen 24f984b51eSPekka Paalanen static struct trace_array *mmio_trace_array; 252039238bSPekka Paalanen static bool overrun_detected; 267ee1768dSPekka Paalanen static unsigned long prev_overruns; 27173ed24eSPekka Paalanen static atomic_t dropped_count; 28f984b51eSPekka Paalanen 29bd8ac686SPekka Paalanen static void mmio_reset_data(struct trace_array *tr) 30bd8ac686SPekka Paalanen { 312039238bSPekka Paalanen overrun_detected = false; 327ee1768dSPekka Paalanen prev_overruns = 0; 33bd8ac686SPekka Paalanen 34213cc060SPekka J Enberg tracing_reset_online_cpus(tr); 35bd8ac686SPekka Paalanen } 36f984b51eSPekka Paalanen 371c80025aSFrederic Weisbecker static int mmio_trace_init(struct trace_array *tr) 38f984b51eSPekka Paalanen { 39f984b51eSPekka Paalanen pr_debug("in %s\n", __func__); 40f984b51eSPekka Paalanen mmio_trace_array = tr; 41c76f0694SSteven Rostedt 42bd8ac686SPekka Paalanen mmio_reset_data(tr); 43f984b51eSPekka Paalanen enable_mmiotrace(); 441c80025aSFrederic Weisbecker return 0; 45f984b51eSPekka Paalanen } 46f984b51eSPekka Paalanen 47f984b51eSPekka Paalanen static void mmio_trace_reset(struct trace_array *tr) 48f984b51eSPekka Paalanen { 49f984b51eSPekka Paalanen pr_debug("in %s\n", __func__); 50c76f0694SSteven Rostedt 51f984b51eSPekka Paalanen disable_mmiotrace(); 52bd8ac686SPekka Paalanen mmio_reset_data(tr); 53bd8ac686SPekka Paalanen mmio_trace_array = NULL; 54f984b51eSPekka Paalanen } 55f984b51eSPekka Paalanen 56bbf5b1a0SSteven Rostedt static void mmio_trace_start(struct trace_array *tr) 57f984b51eSPekka Paalanen { 58f984b51eSPekka Paalanen pr_debug("in %s\n", __func__); 59bd8ac686SPekka Paalanen mmio_reset_data(tr); 60bd8ac686SPekka Paalanen } 61bd8ac686SPekka Paalanen 6213829537SPekka Paalanen static int mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev) 6313829537SPekka Paalanen { 6413829537SPekka Paalanen int ret = 0; 6513829537SPekka Paalanen int i; 6613829537SPekka Paalanen resource_size_t start, end; 6713829537SPekka Paalanen const struct pci_driver *drv = pci_dev_driver(dev); 6813829537SPekka Paalanen 6913829537SPekka Paalanen /* XXX: incomplete checks for trace_seq_printf() return value */ 7013829537SPekka Paalanen ret += trace_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x", 7113829537SPekka Paalanen dev->bus->number, dev->devfn, 7213829537SPekka Paalanen dev->vendor, dev->device, dev->irq); 7313829537SPekka Paalanen /* 7413829537SPekka Paalanen * XXX: is pci_resource_to_user() appropriate, since we are 7513829537SPekka Paalanen * supposed to interpret the __ioremap() phys_addr argument based on 7613829537SPekka Paalanen * these printed values? 7713829537SPekka Paalanen */ 7813829537SPekka Paalanen for (i = 0; i < 7; i++) { 7913829537SPekka Paalanen pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); 8013829537SPekka Paalanen ret += trace_seq_printf(s, " %llx", 8113829537SPekka Paalanen (unsigned long long)(start | 8213829537SPekka Paalanen (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); 8313829537SPekka Paalanen } 8413829537SPekka Paalanen for (i = 0; i < 7; i++) { 8513829537SPekka Paalanen pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); 8613829537SPekka Paalanen ret += trace_seq_printf(s, " %llx", 8713829537SPekka Paalanen dev->resource[i].start < dev->resource[i].end ? 8813829537SPekka Paalanen (unsigned long long)(end - start) + 1 : 0); 8913829537SPekka Paalanen } 9013829537SPekka Paalanen if (drv) 9113829537SPekka Paalanen ret += trace_seq_printf(s, " %s\n", drv->name); 9213829537SPekka Paalanen else 9313829537SPekka Paalanen ret += trace_seq_printf(s, " \n"); 9413829537SPekka Paalanen return ret; 9513829537SPekka Paalanen } 9613829537SPekka Paalanen 97d0a7e8caSPekka Paalanen static void destroy_header_iter(struct header_iter *hiter) 98bd8ac686SPekka Paalanen { 99d0a7e8caSPekka Paalanen if (!hiter) 100d0a7e8caSPekka Paalanen return; 101d0a7e8caSPekka Paalanen pci_dev_put(hiter->dev); 102d0a7e8caSPekka Paalanen kfree(hiter); 103d0a7e8caSPekka Paalanen } 104d0a7e8caSPekka Paalanen 105d0a7e8caSPekka Paalanen static void mmio_pipe_open(struct trace_iterator *iter) 106d0a7e8caSPekka Paalanen { 107d0a7e8caSPekka Paalanen struct header_iter *hiter; 108bd8ac686SPekka Paalanen struct trace_seq *s = &iter->seq; 10913829537SPekka Paalanen 11013829537SPekka Paalanen trace_seq_printf(s, "VERSION 20070824\n"); 11113829537SPekka Paalanen 112d0a7e8caSPekka Paalanen hiter = kzalloc(sizeof(*hiter), GFP_KERNEL); 113d0a7e8caSPekka Paalanen if (!hiter) 114d0a7e8caSPekka Paalanen return; 115d0a7e8caSPekka Paalanen 116d0a7e8caSPekka Paalanen hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); 117d0a7e8caSPekka Paalanen iter->private = hiter; 118d0a7e8caSPekka Paalanen } 119d0a7e8caSPekka Paalanen 120d0a7e8caSPekka Paalanen /* XXX: This is not called when the pipe is closed! */ 121d0a7e8caSPekka Paalanen static void mmio_close(struct trace_iterator *iter) 122d0a7e8caSPekka Paalanen { 123d0a7e8caSPekka Paalanen struct header_iter *hiter = iter->private; 124d0a7e8caSPekka Paalanen destroy_header_iter(hiter); 125d0a7e8caSPekka Paalanen iter->private = NULL; 126d0a7e8caSPekka Paalanen } 127d0a7e8caSPekka Paalanen 1282039238bSPekka Paalanen static unsigned long count_overruns(struct trace_iterator *iter) 1292039238bSPekka Paalanen { 130173ed24eSPekka Paalanen unsigned long cnt = atomic_xchg(&dropped_count, 0); 1317ee1768dSPekka Paalanen unsigned long over = ring_buffer_overruns(iter->tr->buffer); 1327ee1768dSPekka Paalanen 1337ee1768dSPekka Paalanen if (over > prev_overruns) 134173ed24eSPekka Paalanen cnt += over - prev_overruns; 1357ee1768dSPekka Paalanen prev_overruns = over; 1362039238bSPekka Paalanen return cnt; 1372039238bSPekka Paalanen } 1382039238bSPekka Paalanen 139d0a7e8caSPekka Paalanen static ssize_t mmio_read(struct trace_iterator *iter, struct file *filp, 140d0a7e8caSPekka Paalanen char __user *ubuf, size_t cnt, loff_t *ppos) 141d0a7e8caSPekka Paalanen { 142d0a7e8caSPekka Paalanen ssize_t ret; 143d0a7e8caSPekka Paalanen struct header_iter *hiter = iter->private; 144d0a7e8caSPekka Paalanen struct trace_seq *s = &iter->seq; 1452039238bSPekka Paalanen unsigned long n; 1462039238bSPekka Paalanen 1472039238bSPekka Paalanen n = count_overruns(iter); 1482039238bSPekka Paalanen if (n) { 1492039238bSPekka Paalanen /* XXX: This is later than where events were lost. */ 1502039238bSPekka Paalanen trace_seq_printf(s, "MARK 0.000000 Lost %lu events.\n", n); 1512039238bSPekka Paalanen if (!overrun_detected) 1522039238bSPekka Paalanen pr_warning("mmiotrace has lost events.\n"); 1532039238bSPekka Paalanen overrun_detected = true; 1542039238bSPekka Paalanen goto print_out; 1552039238bSPekka Paalanen } 156d0a7e8caSPekka Paalanen 157d0a7e8caSPekka Paalanen if (!hiter) 158d0a7e8caSPekka Paalanen return 0; 159d0a7e8caSPekka Paalanen 160d0a7e8caSPekka Paalanen mmio_print_pcidev(s, hiter->dev); 161d0a7e8caSPekka Paalanen hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, hiter->dev); 162d0a7e8caSPekka Paalanen 163d0a7e8caSPekka Paalanen if (!hiter->dev) { 164d0a7e8caSPekka Paalanen destroy_header_iter(hiter); 165d0a7e8caSPekka Paalanen iter->private = NULL; 166d0a7e8caSPekka Paalanen } 167d0a7e8caSPekka Paalanen 1682039238bSPekka Paalanen print_out: 169d0a7e8caSPekka Paalanen ret = trace_seq_to_user(s, ubuf, cnt); 170d0a7e8caSPekka Paalanen return (ret == -EBUSY) ? 0 : ret; 171bd8ac686SPekka Paalanen } 172bd8ac686SPekka Paalanen 17307f4e4f7SFrederic Weisbecker static enum print_line_t mmio_print_rw(struct trace_iterator *iter) 174bd8ac686SPekka Paalanen { 175bd8ac686SPekka Paalanen struct trace_entry *entry = iter->ent; 1767104f300SSteven Rostedt struct trace_mmiotrace_rw *field; 1777104f300SSteven Rostedt struct mmiotrace_rw *rw; 178bd8ac686SPekka Paalanen struct trace_seq *s = &iter->seq; 1793928a8a2SSteven Rostedt unsigned long long t = ns2usecs(iter->ts); 180a5dec557SLi Zefan unsigned long usec_rem = do_div(t, USEC_PER_SEC); 181bd8ac686SPekka Paalanen unsigned secs = (unsigned long)t; 182bd8ac686SPekka Paalanen int ret = 1; 183bd8ac686SPekka Paalanen 1847104f300SSteven Rostedt trace_assign_type(field, entry); 1857104f300SSteven Rostedt rw = &field->rw; 1867104f300SSteven Rostedt 187777e208dSSteven Rostedt switch (rw->opcode) { 188bd8ac686SPekka Paalanen case MMIO_READ: 189bd8ac686SPekka Paalanen ret = trace_seq_printf(s, 1905e4abc98SSteven Rostedt "R %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n", 191dee310d0SPekka Paalanen rw->width, secs, usec_rem, rw->map_id, 192dee310d0SPekka Paalanen (unsigned long long)rw->phys, 193736ca61fSPekka Paalanen rw->value, rw->pc, 0); 194bd8ac686SPekka Paalanen break; 195bd8ac686SPekka Paalanen case MMIO_WRITE: 196bd8ac686SPekka Paalanen ret = trace_seq_printf(s, 1975e4abc98SSteven Rostedt "W %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n", 198dee310d0SPekka Paalanen rw->width, secs, usec_rem, rw->map_id, 199dee310d0SPekka Paalanen (unsigned long long)rw->phys, 200736ca61fSPekka Paalanen rw->value, rw->pc, 0); 201bd8ac686SPekka Paalanen break; 202bd8ac686SPekka Paalanen case MMIO_UNKNOWN_OP: 203bd8ac686SPekka Paalanen ret = trace_seq_printf(s, 2045e4abc98SSteven Rostedt "UNKNOWN %u.%06lu %d 0x%llx %02lx,%02lx," 2055e4abc98SSteven Rostedt "%02lx 0x%lx %d\n", 206dee310d0SPekka Paalanen secs, usec_rem, rw->map_id, 207dee310d0SPekka Paalanen (unsigned long long)rw->phys, 208bd8ac686SPekka Paalanen (rw->value >> 16) & 0xff, (rw->value >> 8) & 0xff, 209736ca61fSPekka Paalanen (rw->value >> 0) & 0xff, rw->pc, 0); 210bd8ac686SPekka Paalanen break; 211bd8ac686SPekka Paalanen default: 212bd8ac686SPekka Paalanen ret = trace_seq_printf(s, "rw what?\n"); 213bd8ac686SPekka Paalanen break; 214bd8ac686SPekka Paalanen } 215bd8ac686SPekka Paalanen if (ret) 21607f4e4f7SFrederic Weisbecker return TRACE_TYPE_HANDLED; 21707f4e4f7SFrederic Weisbecker return TRACE_TYPE_PARTIAL_LINE; 218bd8ac686SPekka Paalanen } 219bd8ac686SPekka Paalanen 22007f4e4f7SFrederic Weisbecker static enum print_line_t mmio_print_map(struct trace_iterator *iter) 221bd8ac686SPekka Paalanen { 222bd8ac686SPekka Paalanen struct trace_entry *entry = iter->ent; 2237104f300SSteven Rostedt struct trace_mmiotrace_map *field; 2247104f300SSteven Rostedt struct mmiotrace_map *m; 225bd8ac686SPekka Paalanen struct trace_seq *s = &iter->seq; 2263928a8a2SSteven Rostedt unsigned long long t = ns2usecs(iter->ts); 227a5dec557SLi Zefan unsigned long usec_rem = do_div(t, USEC_PER_SEC); 228bd8ac686SPekka Paalanen unsigned secs = (unsigned long)t; 22907f4e4f7SFrederic Weisbecker int ret; 230bd8ac686SPekka Paalanen 2317104f300SSteven Rostedt trace_assign_type(field, entry); 2327104f300SSteven Rostedt m = &field->map; 2337104f300SSteven Rostedt 234777e208dSSteven Rostedt switch (m->opcode) { 235bd8ac686SPekka Paalanen case MMIO_PROBE: 236bd8ac686SPekka Paalanen ret = trace_seq_printf(s, 2375e4abc98SSteven Rostedt "MAP %u.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n", 238dee310d0SPekka Paalanen secs, usec_rem, m->map_id, 239dee310d0SPekka Paalanen (unsigned long long)m->phys, m->virt, m->len, 240e0fd5c2fSPekka Paalanen 0UL, 0); 241bd8ac686SPekka Paalanen break; 242bd8ac686SPekka Paalanen case MMIO_UNPROBE: 243bd8ac686SPekka Paalanen ret = trace_seq_printf(s, 2445e4abc98SSteven Rostedt "UNMAP %u.%06lu %d 0x%lx %d\n", 245e0fd5c2fSPekka Paalanen secs, usec_rem, m->map_id, 0UL, 0); 246bd8ac686SPekka Paalanen break; 247bd8ac686SPekka Paalanen default: 248bd8ac686SPekka Paalanen ret = trace_seq_printf(s, "map what?\n"); 249bd8ac686SPekka Paalanen break; 250bd8ac686SPekka Paalanen } 251bd8ac686SPekka Paalanen if (ret) 25207f4e4f7SFrederic Weisbecker return TRACE_TYPE_HANDLED; 25307f4e4f7SFrederic Weisbecker return TRACE_TYPE_PARTIAL_LINE; 254bd8ac686SPekka Paalanen } 255bd8ac686SPekka Paalanen 25607f4e4f7SFrederic Weisbecker static enum print_line_t mmio_print_mark(struct trace_iterator *iter) 257fc5e27aeSPekka Paalanen { 258fc5e27aeSPekka Paalanen struct trace_entry *entry = iter->ent; 259777e208dSSteven Rostedt struct print_entry *print = (struct print_entry *)entry; 26048ead020SFrederic Weisbecker const char *msg = print->buf; 261fc5e27aeSPekka Paalanen struct trace_seq *s = &iter->seq; 2623928a8a2SSteven Rostedt unsigned long long t = ns2usecs(iter->ts); 263769b0441SFrederic Weisbecker unsigned long usec_rem = do_div(t, USEC_PER_SEC); 264fc5e27aeSPekka Paalanen unsigned secs = (unsigned long)t; 265fc5e27aeSPekka Paalanen int ret; 266fc5e27aeSPekka Paalanen 267fc5e27aeSPekka Paalanen /* The trailing newline must be in the message. */ 26848ead020SFrederic Weisbecker ret = trace_seq_printf(s, "MARK %u.%06lu %s", secs, usec_rem, msg); 269fc5e27aeSPekka Paalanen if (!ret) 27007f4e4f7SFrederic Weisbecker return TRACE_TYPE_PARTIAL_LINE; 271fc5e27aeSPekka Paalanen 27207f4e4f7SFrederic Weisbecker return TRACE_TYPE_HANDLED; 273fc5e27aeSPekka Paalanen } 274fc5e27aeSPekka Paalanen 27507f4e4f7SFrederic Weisbecker static enum print_line_t mmio_print_line(struct trace_iterator *iter) 276bd8ac686SPekka Paalanen { 277bd8ac686SPekka Paalanen switch (iter->ent->type) { 278bd8ac686SPekka Paalanen case TRACE_MMIO_RW: 279bd8ac686SPekka Paalanen return mmio_print_rw(iter); 280bd8ac686SPekka Paalanen case TRACE_MMIO_MAP: 281bd8ac686SPekka Paalanen return mmio_print_map(iter); 282fc5e27aeSPekka Paalanen case TRACE_PRINT: 283fc5e27aeSPekka Paalanen return mmio_print_mark(iter); 284bd8ac686SPekka Paalanen default: 28507f4e4f7SFrederic Weisbecker return TRACE_TYPE_HANDLED; /* ignore unknown entries */ 286bd8ac686SPekka Paalanen } 287bd8ac686SPekka Paalanen } 288f984b51eSPekka Paalanen 289f984b51eSPekka Paalanen static struct tracer mmio_tracer __read_mostly = 290f984b51eSPekka Paalanen { 291f984b51eSPekka Paalanen .name = "mmiotrace", 292f984b51eSPekka Paalanen .init = mmio_trace_init, 293f984b51eSPekka Paalanen .reset = mmio_trace_reset, 294bbf5b1a0SSteven Rostedt .start = mmio_trace_start, 295d0a7e8caSPekka Paalanen .pipe_open = mmio_pipe_open, 296d0a7e8caSPekka Paalanen .close = mmio_close, 297d0a7e8caSPekka Paalanen .read = mmio_read, 298bd8ac686SPekka Paalanen .print_line = mmio_print_line, 299f984b51eSPekka Paalanen }; 300f984b51eSPekka Paalanen 301f984b51eSPekka Paalanen __init static int init_mmio_trace(void) 302f984b51eSPekka Paalanen { 303f984b51eSPekka Paalanen return register_tracer(&mmio_tracer); 304f984b51eSPekka Paalanen } 305f984b51eSPekka Paalanen device_initcall(init_mmio_trace); 306f984b51eSPekka Paalanen 30745dcd8b8SPekka Paalanen static void __trace_mmiotrace_rw(struct trace_array *tr, 30845dcd8b8SPekka Paalanen struct trace_array_cpu *data, 30945dcd8b8SPekka Paalanen struct mmiotrace_rw *rw) 31045dcd8b8SPekka Paalanen { 31160ba7702SSteven Rostedt struct ftrace_event_call *call = &event_mmiotrace_rw; 312e77405adSSteven Rostedt struct ring_buffer *buffer = tr->buffer; 3133928a8a2SSteven Rostedt struct ring_buffer_event *event; 314777e208dSSteven Rostedt struct trace_mmiotrace_rw *entry; 31551a763ddSArnaldo Carvalho de Melo int pc = preempt_count(); 31645dcd8b8SPekka Paalanen 317e77405adSSteven Rostedt event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_RW, 31851a763ddSArnaldo Carvalho de Melo sizeof(*entry), 0, pc); 319173ed24eSPekka Paalanen if (!event) { 320173ed24eSPekka Paalanen atomic_inc(&dropped_count); 3213928a8a2SSteven Rostedt return; 322173ed24eSPekka Paalanen } 3233928a8a2SSteven Rostedt entry = ring_buffer_event_data(event); 324777e208dSSteven Rostedt entry->rw = *rw; 32560ba7702SSteven Rostedt 32660ba7702SSteven Rostedt if (!filter_check_discard(call, entry, buffer, event)) 327e77405adSSteven Rostedt trace_buffer_unlock_commit(buffer, event, 0, pc); 32845dcd8b8SPekka Paalanen } 32945dcd8b8SPekka Paalanen 330bd8ac686SPekka Paalanen void mmio_trace_rw(struct mmiotrace_rw *rw) 331f984b51eSPekka Paalanen { 332f984b51eSPekka Paalanen struct trace_array *tr = mmio_trace_array; 333f984b51eSPekka Paalanen struct trace_array_cpu *data = tr->data[smp_processor_id()]; 334bd8ac686SPekka Paalanen __trace_mmiotrace_rw(tr, data, rw); 335bd8ac686SPekka Paalanen } 336f984b51eSPekka Paalanen 33745dcd8b8SPekka Paalanen static void __trace_mmiotrace_map(struct trace_array *tr, 33845dcd8b8SPekka Paalanen struct trace_array_cpu *data, 33945dcd8b8SPekka Paalanen struct mmiotrace_map *map) 34045dcd8b8SPekka Paalanen { 34160ba7702SSteven Rostedt struct ftrace_event_call *call = &event_mmiotrace_map; 342e77405adSSteven Rostedt struct ring_buffer *buffer = tr->buffer; 3433928a8a2SSteven Rostedt struct ring_buffer_event *event; 344777e208dSSteven Rostedt struct trace_mmiotrace_map *entry; 34551a763ddSArnaldo Carvalho de Melo int pc = preempt_count(); 34645dcd8b8SPekka Paalanen 347e77405adSSteven Rostedt event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_MAP, 34851a763ddSArnaldo Carvalho de Melo sizeof(*entry), 0, pc); 349173ed24eSPekka Paalanen if (!event) { 350173ed24eSPekka Paalanen atomic_inc(&dropped_count); 3513928a8a2SSteven Rostedt return; 352173ed24eSPekka Paalanen } 3533928a8a2SSteven Rostedt entry = ring_buffer_event_data(event); 354777e208dSSteven Rostedt entry->map = *map; 35560ba7702SSteven Rostedt 35660ba7702SSteven Rostedt if (!filter_check_discard(call, entry, buffer, event)) 357e77405adSSteven Rostedt trace_buffer_unlock_commit(buffer, event, 0, pc); 35845dcd8b8SPekka Paalanen } 35945dcd8b8SPekka Paalanen 360bd8ac686SPekka Paalanen void mmio_trace_mapping(struct mmiotrace_map *map) 361bd8ac686SPekka Paalanen { 362bd8ac686SPekka Paalanen struct trace_array *tr = mmio_trace_array; 363bd8ac686SPekka Paalanen struct trace_array_cpu *data; 364bd8ac686SPekka Paalanen 365bd8ac686SPekka Paalanen preempt_disable(); 366bd8ac686SPekka Paalanen data = tr->data[smp_processor_id()]; 367bd8ac686SPekka Paalanen __trace_mmiotrace_map(tr, data, map); 368bd8ac686SPekka Paalanen preempt_enable(); 369f984b51eSPekka Paalanen } 3709e57fb35SPekka Paalanen 3719e57fb35SPekka Paalanen int mmio_trace_printk(const char *fmt, va_list args) 3729e57fb35SPekka Paalanen { 37340ce74f1SSteven Rostedt return trace_vprintk(0, fmt, args); 3749e57fb35SPekka Paalanen } 375