xref: /linux/drivers/hwtracing/stm/ftrace.c (revision a773d419275bf54854ca6cfda8f2594ed2790faa)
1262e1f6eSChunyan Zhang /*
2262e1f6eSChunyan Zhang  * Simple kernel driver to link kernel Ftrace and an STM device
3262e1f6eSChunyan Zhang  * Copyright (c) 2016, Linaro Ltd.
4262e1f6eSChunyan Zhang  *
5262e1f6eSChunyan Zhang  * This program is free software; you can redistribute it and/or modify it
6262e1f6eSChunyan Zhang  * under the terms and conditions of the GNU General Public License,
7262e1f6eSChunyan Zhang  * version 2, as published by the Free Software Foundation.
8262e1f6eSChunyan Zhang  *
9262e1f6eSChunyan Zhang  * This program is distributed in the hope it will be useful, but WITHOUT
10262e1f6eSChunyan Zhang  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11262e1f6eSChunyan Zhang  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12262e1f6eSChunyan Zhang  * more details.
13262e1f6eSChunyan Zhang  *
14262e1f6eSChunyan Zhang  * STM Ftrace will be registered as a trace_export.
15262e1f6eSChunyan Zhang  */
16262e1f6eSChunyan Zhang 
17262e1f6eSChunyan Zhang #include <linux/module.h>
18262e1f6eSChunyan Zhang #include <linux/stm.h>
19262e1f6eSChunyan Zhang #include <linux/trace.h>
20262e1f6eSChunyan Zhang 
21262e1f6eSChunyan Zhang #define STM_FTRACE_NR_CHANNELS 1
22262e1f6eSChunyan Zhang #define STM_FTRACE_CHAN 0
23262e1f6eSChunyan Zhang 
24262e1f6eSChunyan Zhang static int stm_ftrace_link(struct stm_source_data *data);
25262e1f6eSChunyan Zhang static void stm_ftrace_unlink(struct stm_source_data *data);
26262e1f6eSChunyan Zhang 
27262e1f6eSChunyan Zhang static struct stm_ftrace {
28262e1f6eSChunyan Zhang 	struct stm_source_data	data;
29262e1f6eSChunyan Zhang 	struct trace_export	ftrace;
30262e1f6eSChunyan Zhang } stm_ftrace = {
31262e1f6eSChunyan Zhang 	.data	= {
32262e1f6eSChunyan Zhang 		.name		= "ftrace",
33262e1f6eSChunyan Zhang 		.nr_chans	= STM_FTRACE_NR_CHANNELS,
34262e1f6eSChunyan Zhang 		.link		= stm_ftrace_link,
35262e1f6eSChunyan Zhang 		.unlink		= stm_ftrace_unlink,
36262e1f6eSChunyan Zhang 	},
37262e1f6eSChunyan Zhang };
38262e1f6eSChunyan Zhang 
39262e1f6eSChunyan Zhang /**
40262e1f6eSChunyan Zhang  * stm_ftrace_write() - write data to STM via 'stm_ftrace' source
41262e1f6eSChunyan Zhang  * @buf:	buffer containing the data packet
42262e1f6eSChunyan Zhang  * @len:	length of the data packet
43262e1f6eSChunyan Zhang  */
44262e1f6eSChunyan Zhang static void notrace
45*a773d419SFelipe Balbi stm_ftrace_write(struct trace_export *export, const void *buf, unsigned int len)
46262e1f6eSChunyan Zhang {
47*a773d419SFelipe Balbi 	struct stm_ftrace *stm = container_of(export, struct stm_ftrace, ftrace);
48*a773d419SFelipe Balbi 
49*a773d419SFelipe Balbi 	stm_source_write(&stm->data, STM_FTRACE_CHAN, buf, len);
50262e1f6eSChunyan Zhang }
51262e1f6eSChunyan Zhang 
52262e1f6eSChunyan Zhang static int stm_ftrace_link(struct stm_source_data *data)
53262e1f6eSChunyan Zhang {
54262e1f6eSChunyan Zhang 	struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
55262e1f6eSChunyan Zhang 
56262e1f6eSChunyan Zhang 	sf->ftrace.write = stm_ftrace_write;
57262e1f6eSChunyan Zhang 
58262e1f6eSChunyan Zhang 	return register_ftrace_export(&sf->ftrace);
59262e1f6eSChunyan Zhang }
60262e1f6eSChunyan Zhang 
61262e1f6eSChunyan Zhang static void stm_ftrace_unlink(struct stm_source_data *data)
62262e1f6eSChunyan Zhang {
63262e1f6eSChunyan Zhang 	struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
64262e1f6eSChunyan Zhang 
65262e1f6eSChunyan Zhang 	unregister_ftrace_export(&sf->ftrace);
66262e1f6eSChunyan Zhang }
67262e1f6eSChunyan Zhang 
68262e1f6eSChunyan Zhang static int __init stm_ftrace_init(void)
69262e1f6eSChunyan Zhang {
70262e1f6eSChunyan Zhang 	int ret;
71262e1f6eSChunyan Zhang 
72262e1f6eSChunyan Zhang 	ret = stm_source_register_device(NULL, &stm_ftrace.data);
73262e1f6eSChunyan Zhang 	if (ret)
74262e1f6eSChunyan Zhang 		pr_err("Failed to register stm_source - ftrace.\n");
75262e1f6eSChunyan Zhang 
76262e1f6eSChunyan Zhang 	return ret;
77262e1f6eSChunyan Zhang }
78262e1f6eSChunyan Zhang 
79262e1f6eSChunyan Zhang static void __exit stm_ftrace_exit(void)
80262e1f6eSChunyan Zhang {
81262e1f6eSChunyan Zhang 	stm_source_unregister_device(&stm_ftrace.data);
82262e1f6eSChunyan Zhang }
83262e1f6eSChunyan Zhang 
84262e1f6eSChunyan Zhang module_init(stm_ftrace_init);
85262e1f6eSChunyan Zhang module_exit(stm_ftrace_exit);
86262e1f6eSChunyan Zhang 
87262e1f6eSChunyan Zhang MODULE_LICENSE("GPL v2");
88262e1f6eSChunyan Zhang MODULE_DESCRIPTION("stm_ftrace driver");
89262e1f6eSChunyan Zhang MODULE_AUTHOR("Chunyan Zhang <zhang.chunyan@linaro.org>");
90