Linux Audio

Check our new training course

Loading...
v4.10.11
 
  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#include <linux/pci.h>
 12#include <linux/slab.h>
 13#include <linux/time.h>
 14
 15#include <linux/atomic.h>
 16
 17#include "trace.h"
 18#include "trace_output.h"
 19
 20struct header_iter {
 21	struct pci_dev *dev;
 22};
 23
 24static struct trace_array *mmio_trace_array;
 25static bool overrun_detected;
 26static unsigned long prev_overruns;
 27static atomic_t dropped_count;
 28
 29static void mmio_reset_data(struct trace_array *tr)
 30{
 31	overrun_detected = false;
 32	prev_overruns = 0;
 33
 34	tracing_reset_online_cpus(&tr->trace_buffer);
 35}
 36
 37static int mmio_trace_init(struct trace_array *tr)
 38{
 39	pr_debug("in %s\n", __func__);
 40	mmio_trace_array = tr;
 41
 42	mmio_reset_data(tr);
 43	enable_mmiotrace();
 44	return 0;
 45}
 46
 47static void mmio_trace_reset(struct trace_array *tr)
 48{
 49	pr_debug("in %s\n", __func__);
 50
 51	disable_mmiotrace();
 52	mmio_reset_data(tr);
 53	mmio_trace_array = NULL;
 54}
 55
 56static void mmio_trace_start(struct trace_array *tr)
 57{
 58	pr_debug("in %s\n", __func__);
 59	mmio_reset_data(tr);
 60}
 61
 62static void mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev)
 63{
 64	int i;
 65	resource_size_t start, end;
 66	const struct pci_driver *drv = pci_dev_driver(dev);
 67
 68	trace_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x",
 69			 dev->bus->number, dev->devfn,
 70			 dev->vendor, dev->device, dev->irq);
 71	for (i = 0; i < 7; i++) {
 72		start = dev->resource[i].start;
 73		trace_seq_printf(s, " %llx",
 74			(unsigned long long)(start |
 75			(dev->resource[i].flags & PCI_REGION_FLAG_MASK)));
 76	}
 77	for (i = 0; i < 7; i++) {
 78		start = dev->resource[i].start;
 79		end = dev->resource[i].end;
 80		trace_seq_printf(s, " %llx",
 81			dev->resource[i].start < dev->resource[i].end ?
 82			(unsigned long long)(end - start) + 1 : 0);
 83	}
 84	if (drv)
 85		trace_seq_printf(s, " %s\n", drv->name);
 86	else
 87		trace_seq_puts(s, " \n");
 88}
 89
 90static void destroy_header_iter(struct header_iter *hiter)
 91{
 92	if (!hiter)
 93		return;
 94	pci_dev_put(hiter->dev);
 95	kfree(hiter);
 96}
 97
 98static void mmio_pipe_open(struct trace_iterator *iter)
 99{
100	struct header_iter *hiter;
101	struct trace_seq *s = &iter->seq;
102
103	trace_seq_puts(s, "VERSION 20070824\n");
104
105	hiter = kzalloc(sizeof(*hiter), GFP_KERNEL);
106	if (!hiter)
107		return;
108
109	hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
110	iter->private = hiter;
111}
112
113/* XXX: This is not called when the pipe is closed! */
114static void mmio_close(struct trace_iterator *iter)
115{
116	struct header_iter *hiter = iter->private;
117	destroy_header_iter(hiter);
118	iter->private = NULL;
119}
120
121static unsigned long count_overruns(struct trace_iterator *iter)
122{
123	unsigned long cnt = atomic_xchg(&dropped_count, 0);
124	unsigned long over = ring_buffer_overruns(iter->trace_buffer->buffer);
125
126	if (over > prev_overruns)
127		cnt += over - prev_overruns;
128	prev_overruns = over;
129	return cnt;
130}
131
132static ssize_t mmio_read(struct trace_iterator *iter, struct file *filp,
133				char __user *ubuf, size_t cnt, loff_t *ppos)
134{
135	ssize_t ret;
136	struct header_iter *hiter = iter->private;
137	struct trace_seq *s = &iter->seq;
138	unsigned long n;
139
140	n = count_overruns(iter);
141	if (n) {
142		/* XXX: This is later than where events were lost. */
143		trace_seq_printf(s, "MARK 0.000000 Lost %lu events.\n", n);
144		if (!overrun_detected)
145			pr_warn("mmiotrace has lost events\n");
146		overrun_detected = true;
147		goto print_out;
148	}
149
150	if (!hiter)
151		return 0;
152
153	mmio_print_pcidev(s, hiter->dev);
154	hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, hiter->dev);
155
156	if (!hiter->dev) {
157		destroy_header_iter(hiter);
158		iter->private = NULL;
159	}
160
161print_out:
162	ret = trace_seq_to_user(s, ubuf, cnt);
163	return (ret == -EBUSY) ? 0 : ret;
164}
165
166static enum print_line_t mmio_print_rw(struct trace_iterator *iter)
167{
168	struct trace_entry *entry = iter->ent;
169	struct trace_mmiotrace_rw *field;
170	struct mmiotrace_rw *rw;
171	struct trace_seq *s	= &iter->seq;
172	unsigned long long t	= ns2usecs(iter->ts);
173	unsigned long usec_rem	= do_div(t, USEC_PER_SEC);
174	unsigned secs		= (unsigned long)t;
175
176	trace_assign_type(field, entry);
177	rw = &field->rw;
178
179	switch (rw->opcode) {
180	case MMIO_READ:
181		trace_seq_printf(s,
182			"R %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
183			rw->width, secs, usec_rem, rw->map_id,
184			(unsigned long long)rw->phys,
185			rw->value, rw->pc, 0);
186		break;
187	case MMIO_WRITE:
188		trace_seq_printf(s,
189			"W %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
190			rw->width, secs, usec_rem, rw->map_id,
191			(unsigned long long)rw->phys,
192			rw->value, rw->pc, 0);
193		break;
194	case MMIO_UNKNOWN_OP:
195		trace_seq_printf(s,
196			"UNKNOWN %u.%06lu %d 0x%llx %02lx,%02lx,"
197			"%02lx 0x%lx %d\n",
198			secs, usec_rem, rw->map_id,
199			(unsigned long long)rw->phys,
200			(rw->value >> 16) & 0xff, (rw->value >> 8) & 0xff,
201			(rw->value >> 0) & 0xff, rw->pc, 0);
202		break;
203	default:
204		trace_seq_puts(s, "rw what?\n");
205		break;
206	}
207
208	return trace_handle_return(s);
209}
210
211static enum print_line_t mmio_print_map(struct trace_iterator *iter)
212{
213	struct trace_entry *entry = iter->ent;
214	struct trace_mmiotrace_map *field;
215	struct mmiotrace_map *m;
216	struct trace_seq *s	= &iter->seq;
217	unsigned long long t	= ns2usecs(iter->ts);
218	unsigned long usec_rem	= do_div(t, USEC_PER_SEC);
219	unsigned secs		= (unsigned long)t;
220
221	trace_assign_type(field, entry);
222	m = &field->map;
223
224	switch (m->opcode) {
225	case MMIO_PROBE:
226		trace_seq_printf(s,
227			"MAP %u.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n",
228			secs, usec_rem, m->map_id,
229			(unsigned long long)m->phys, m->virt, m->len,
230			0UL, 0);
231		break;
232	case MMIO_UNPROBE:
233		trace_seq_printf(s,
234			"UNMAP %u.%06lu %d 0x%lx %d\n",
235			secs, usec_rem, m->map_id, 0UL, 0);
236		break;
237	default:
238		trace_seq_puts(s, "map what?\n");
239		break;
240	}
241
242	return trace_handle_return(s);
243}
244
245static enum print_line_t mmio_print_mark(struct trace_iterator *iter)
246{
247	struct trace_entry *entry = iter->ent;
248	struct print_entry *print = (struct print_entry *)entry;
249	const char *msg		= print->buf;
250	struct trace_seq *s	= &iter->seq;
251	unsigned long long t	= ns2usecs(iter->ts);
252	unsigned long usec_rem	= do_div(t, USEC_PER_SEC);
253	unsigned secs		= (unsigned long)t;
254
255	/* The trailing newline must be in the message. */
256	trace_seq_printf(s, "MARK %u.%06lu %s", secs, usec_rem, msg);
257
258	return trace_handle_return(s);
259}
260
261static enum print_line_t mmio_print_line(struct trace_iterator *iter)
262{
263	switch (iter->ent->type) {
264	case TRACE_MMIO_RW:
265		return mmio_print_rw(iter);
266	case TRACE_MMIO_MAP:
267		return mmio_print_map(iter);
268	case TRACE_PRINT:
269		return mmio_print_mark(iter);
270	default:
271		return TRACE_TYPE_HANDLED; /* ignore unknown entries */
272	}
273}
274
275static struct tracer mmio_tracer __read_mostly =
276{
277	.name		= "mmiotrace",
278	.init		= mmio_trace_init,
279	.reset		= mmio_trace_reset,
280	.start		= mmio_trace_start,
281	.pipe_open	= mmio_pipe_open,
282	.close		= mmio_close,
283	.read		= mmio_read,
284	.print_line	= mmio_print_line,
 
285};
286
287__init static int init_mmio_trace(void)
288{
289	return register_tracer(&mmio_tracer);
290}
291device_initcall(init_mmio_trace);
292
293static void __trace_mmiotrace_rw(struct trace_array *tr,
294				struct trace_array_cpu *data,
295				struct mmiotrace_rw *rw)
296{
297	struct trace_event_call *call = &event_mmiotrace_rw;
298	struct ring_buffer *buffer = tr->trace_buffer.buffer;
299	struct ring_buffer_event *event;
300	struct trace_mmiotrace_rw *entry;
301	int pc = preempt_count();
302
303	event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_RW,
304					  sizeof(*entry), 0, pc);
305	if (!event) {
306		atomic_inc(&dropped_count);
307		return;
308	}
309	entry	= ring_buffer_event_data(event);
310	entry->rw			= *rw;
311
312	if (!call_filter_check_discard(call, entry, buffer, event))
313		trace_buffer_unlock_commit(tr, buffer, event, 0, pc);
314}
315
316void mmio_trace_rw(struct mmiotrace_rw *rw)
317{
318	struct trace_array *tr = mmio_trace_array;
319	struct trace_array_cpu *data = per_cpu_ptr(tr->trace_buffer.data, smp_processor_id());
320	__trace_mmiotrace_rw(tr, data, rw);
321}
322
323static void __trace_mmiotrace_map(struct trace_array *tr,
324				struct trace_array_cpu *data,
325				struct mmiotrace_map *map)
326{
327	struct trace_event_call *call = &event_mmiotrace_map;
328	struct ring_buffer *buffer = tr->trace_buffer.buffer;
329	struct ring_buffer_event *event;
330	struct trace_mmiotrace_map *entry;
331	int pc = preempt_count();
332
333	event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_MAP,
334					  sizeof(*entry), 0, pc);
335	if (!event) {
336		atomic_inc(&dropped_count);
337		return;
338	}
339	entry	= ring_buffer_event_data(event);
340	entry->map			= *map;
341
342	if (!call_filter_check_discard(call, entry, buffer, event))
343		trace_buffer_unlock_commit(tr, buffer, event, 0, pc);
344}
345
346void mmio_trace_mapping(struct mmiotrace_map *map)
347{
348	struct trace_array *tr = mmio_trace_array;
349	struct trace_array_cpu *data;
350
351	preempt_disable();
352	data = per_cpu_ptr(tr->trace_buffer.data, smp_processor_id());
353	__trace_mmiotrace_map(tr, data, map);
354	preempt_enable();
355}
356
357int mmio_trace_printk(const char *fmt, va_list args)
358{
359	return trace_vprintk(0, fmt, args);
360}
v5.9
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Memory mapped I/O tracing
  4 *
  5 * Copyright (C) 2008 Pekka Paalanen <pq@iki.fi>
  6 */
  7
  8#define DEBUG 1
  9
 10#include <linux/kernel.h>
 11#include <linux/mmiotrace.h>
 12#include <linux/pci.h>
 13#include <linux/slab.h>
 14#include <linux/time.h>
 15
 16#include <linux/atomic.h>
 17
 18#include "trace.h"
 19#include "trace_output.h"
 20
 21struct header_iter {
 22	struct pci_dev *dev;
 23};
 24
 25static struct trace_array *mmio_trace_array;
 26static bool overrun_detected;
 27static unsigned long prev_overruns;
 28static atomic_t dropped_count;
 29
 30static void mmio_reset_data(struct trace_array *tr)
 31{
 32	overrun_detected = false;
 33	prev_overruns = 0;
 34
 35	tracing_reset_online_cpus(&tr->array_buffer);
 36}
 37
 38static int mmio_trace_init(struct trace_array *tr)
 39{
 40	pr_debug("in %s\n", __func__);
 41	mmio_trace_array = tr;
 42
 43	mmio_reset_data(tr);
 44	enable_mmiotrace();
 45	return 0;
 46}
 47
 48static void mmio_trace_reset(struct trace_array *tr)
 49{
 50	pr_debug("in %s\n", __func__);
 51
 52	disable_mmiotrace();
 53	mmio_reset_data(tr);
 54	mmio_trace_array = NULL;
 55}
 56
 57static void mmio_trace_start(struct trace_array *tr)
 58{
 59	pr_debug("in %s\n", __func__);
 60	mmio_reset_data(tr);
 61}
 62
 63static void mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev)
 64{
 65	int i;
 66	resource_size_t start, end;
 67	const struct pci_driver *drv = pci_dev_driver(dev);
 68
 69	trace_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x",
 70			 dev->bus->number, dev->devfn,
 71			 dev->vendor, dev->device, dev->irq);
 72	for (i = 0; i < 7; i++) {
 73		start = dev->resource[i].start;
 74		trace_seq_printf(s, " %llx",
 75			(unsigned long long)(start |
 76			(dev->resource[i].flags & PCI_REGION_FLAG_MASK)));
 77	}
 78	for (i = 0; i < 7; i++) {
 79		start = dev->resource[i].start;
 80		end = dev->resource[i].end;
 81		trace_seq_printf(s, " %llx",
 82			dev->resource[i].start < dev->resource[i].end ?
 83			(unsigned long long)(end - start) + 1 : 0);
 84	}
 85	if (drv)
 86		trace_seq_printf(s, " %s\n", drv->name);
 87	else
 88		trace_seq_puts(s, " \n");
 89}
 90
 91static void destroy_header_iter(struct header_iter *hiter)
 92{
 93	if (!hiter)
 94		return;
 95	pci_dev_put(hiter->dev);
 96	kfree(hiter);
 97}
 98
 99static void mmio_pipe_open(struct trace_iterator *iter)
100{
101	struct header_iter *hiter;
102	struct trace_seq *s = &iter->seq;
103
104	trace_seq_puts(s, "VERSION 20070824\n");
105
106	hiter = kzalloc(sizeof(*hiter), GFP_KERNEL);
107	if (!hiter)
108		return;
109
110	hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
111	iter->private = hiter;
112}
113
114/* XXX: This is not called when the pipe is closed! */
115static void mmio_close(struct trace_iterator *iter)
116{
117	struct header_iter *hiter = iter->private;
118	destroy_header_iter(hiter);
119	iter->private = NULL;
120}
121
122static unsigned long count_overruns(struct trace_iterator *iter)
123{
124	unsigned long cnt = atomic_xchg(&dropped_count, 0);
125	unsigned long over = ring_buffer_overruns(iter->array_buffer->buffer);
126
127	if (over > prev_overruns)
128		cnt += over - prev_overruns;
129	prev_overruns = over;
130	return cnt;
131}
132
133static ssize_t mmio_read(struct trace_iterator *iter, struct file *filp,
134				char __user *ubuf, size_t cnt, loff_t *ppos)
135{
136	ssize_t ret;
137	struct header_iter *hiter = iter->private;
138	struct trace_seq *s = &iter->seq;
139	unsigned long n;
140
141	n = count_overruns(iter);
142	if (n) {
143		/* XXX: This is later than where events were lost. */
144		trace_seq_printf(s, "MARK 0.000000 Lost %lu events.\n", n);
145		if (!overrun_detected)
146			pr_warn("mmiotrace has lost events\n");
147		overrun_detected = true;
148		goto print_out;
149	}
150
151	if (!hiter)
152		return 0;
153
154	mmio_print_pcidev(s, hiter->dev);
155	hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, hiter->dev);
156
157	if (!hiter->dev) {
158		destroy_header_iter(hiter);
159		iter->private = NULL;
160	}
161
162print_out:
163	ret = trace_seq_to_user(s, ubuf, cnt);
164	return (ret == -EBUSY) ? 0 : ret;
165}
166
167static enum print_line_t mmio_print_rw(struct trace_iterator *iter)
168{
169	struct trace_entry *entry = iter->ent;
170	struct trace_mmiotrace_rw *field;
171	struct mmiotrace_rw *rw;
172	struct trace_seq *s	= &iter->seq;
173	unsigned long long t	= ns2usecs(iter->ts);
174	unsigned long usec_rem	= do_div(t, USEC_PER_SEC);
175	unsigned secs		= (unsigned long)t;
176
177	trace_assign_type(field, entry);
178	rw = &field->rw;
179
180	switch (rw->opcode) {
181	case MMIO_READ:
182		trace_seq_printf(s,
183			"R %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
184			rw->width, secs, usec_rem, rw->map_id,
185			(unsigned long long)rw->phys,
186			rw->value, rw->pc, 0);
187		break;
188	case MMIO_WRITE:
189		trace_seq_printf(s,
190			"W %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
191			rw->width, secs, usec_rem, rw->map_id,
192			(unsigned long long)rw->phys,
193			rw->value, rw->pc, 0);
194		break;
195	case MMIO_UNKNOWN_OP:
196		trace_seq_printf(s,
197			"UNKNOWN %u.%06lu %d 0x%llx %02lx,%02lx,"
198			"%02lx 0x%lx %d\n",
199			secs, usec_rem, rw->map_id,
200			(unsigned long long)rw->phys,
201			(rw->value >> 16) & 0xff, (rw->value >> 8) & 0xff,
202			(rw->value >> 0) & 0xff, rw->pc, 0);
203		break;
204	default:
205		trace_seq_puts(s, "rw what?\n");
206		break;
207	}
208
209	return trace_handle_return(s);
210}
211
212static enum print_line_t mmio_print_map(struct trace_iterator *iter)
213{
214	struct trace_entry *entry = iter->ent;
215	struct trace_mmiotrace_map *field;
216	struct mmiotrace_map *m;
217	struct trace_seq *s	= &iter->seq;
218	unsigned long long t	= ns2usecs(iter->ts);
219	unsigned long usec_rem	= do_div(t, USEC_PER_SEC);
220	unsigned secs		= (unsigned long)t;
221
222	trace_assign_type(field, entry);
223	m = &field->map;
224
225	switch (m->opcode) {
226	case MMIO_PROBE:
227		trace_seq_printf(s,
228			"MAP %u.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n",
229			secs, usec_rem, m->map_id,
230			(unsigned long long)m->phys, m->virt, m->len,
231			0UL, 0);
232		break;
233	case MMIO_UNPROBE:
234		trace_seq_printf(s,
235			"UNMAP %u.%06lu %d 0x%lx %d\n",
236			secs, usec_rem, m->map_id, 0UL, 0);
237		break;
238	default:
239		trace_seq_puts(s, "map what?\n");
240		break;
241	}
242
243	return trace_handle_return(s);
244}
245
246static enum print_line_t mmio_print_mark(struct trace_iterator *iter)
247{
248	struct trace_entry *entry = iter->ent;
249	struct print_entry *print = (struct print_entry *)entry;
250	const char *msg		= print->buf;
251	struct trace_seq *s	= &iter->seq;
252	unsigned long long t	= ns2usecs(iter->ts);
253	unsigned long usec_rem	= do_div(t, USEC_PER_SEC);
254	unsigned secs		= (unsigned long)t;
255
256	/* The trailing newline must be in the message. */
257	trace_seq_printf(s, "MARK %u.%06lu %s", secs, usec_rem, msg);
258
259	return trace_handle_return(s);
260}
261
262static enum print_line_t mmio_print_line(struct trace_iterator *iter)
263{
264	switch (iter->ent->type) {
265	case TRACE_MMIO_RW:
266		return mmio_print_rw(iter);
267	case TRACE_MMIO_MAP:
268		return mmio_print_map(iter);
269	case TRACE_PRINT:
270		return mmio_print_mark(iter);
271	default:
272		return TRACE_TYPE_HANDLED; /* ignore unknown entries */
273	}
274}
275
276static struct tracer mmio_tracer __read_mostly =
277{
278	.name		= "mmiotrace",
279	.init		= mmio_trace_init,
280	.reset		= mmio_trace_reset,
281	.start		= mmio_trace_start,
282	.pipe_open	= mmio_pipe_open,
283	.close		= mmio_close,
284	.read		= mmio_read,
285	.print_line	= mmio_print_line,
286	.noboot		= true,
287};
288
289__init static int init_mmio_trace(void)
290{
291	return register_tracer(&mmio_tracer);
292}
293device_initcall(init_mmio_trace);
294
295static void __trace_mmiotrace_rw(struct trace_array *tr,
296				struct trace_array_cpu *data,
297				struct mmiotrace_rw *rw)
298{
299	struct trace_event_call *call = &event_mmiotrace_rw;
300	struct trace_buffer *buffer = tr->array_buffer.buffer;
301	struct ring_buffer_event *event;
302	struct trace_mmiotrace_rw *entry;
303	int pc = preempt_count();
304
305	event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_RW,
306					  sizeof(*entry), 0, pc);
307	if (!event) {
308		atomic_inc(&dropped_count);
309		return;
310	}
311	entry	= ring_buffer_event_data(event);
312	entry->rw			= *rw;
313
314	if (!call_filter_check_discard(call, entry, buffer, event))
315		trace_buffer_unlock_commit(tr, buffer, event, 0, pc);
316}
317
318void mmio_trace_rw(struct mmiotrace_rw *rw)
319{
320	struct trace_array *tr = mmio_trace_array;
321	struct trace_array_cpu *data = per_cpu_ptr(tr->array_buffer.data, smp_processor_id());
322	__trace_mmiotrace_rw(tr, data, rw);
323}
324
325static void __trace_mmiotrace_map(struct trace_array *tr,
326				struct trace_array_cpu *data,
327				struct mmiotrace_map *map)
328{
329	struct trace_event_call *call = &event_mmiotrace_map;
330	struct trace_buffer *buffer = tr->array_buffer.buffer;
331	struct ring_buffer_event *event;
332	struct trace_mmiotrace_map *entry;
333	int pc = preempt_count();
334
335	event = trace_buffer_lock_reserve(buffer, TRACE_MMIO_MAP,
336					  sizeof(*entry), 0, pc);
337	if (!event) {
338		atomic_inc(&dropped_count);
339		return;
340	}
341	entry	= ring_buffer_event_data(event);
342	entry->map			= *map;
343
344	if (!call_filter_check_discard(call, entry, buffer, event))
345		trace_buffer_unlock_commit(tr, buffer, event, 0, pc);
346}
347
348void mmio_trace_mapping(struct mmiotrace_map *map)
349{
350	struct trace_array *tr = mmio_trace_array;
351	struct trace_array_cpu *data;
352
353	preempt_disable();
354	data = per_cpu_ptr(tr->array_buffer.data, smp_processor_id());
355	__trace_mmiotrace_map(tr, data, map);
356	preempt_enable();
357}
358
359int mmio_trace_printk(const char *fmt, va_list args)
360{
361	return trace_vprintk(0, fmt, args);
362}