xref: /linux/drivers/hwtracing/stm/ftrace.c (revision 262e1f6e39143c2a0f559e2fb4a835069a7693a9)
1*262e1f6eSChunyan Zhang /*
2*262e1f6eSChunyan Zhang  * Simple kernel driver to link kernel Ftrace and an STM device
3*262e1f6eSChunyan Zhang  * Copyright (c) 2016, Linaro Ltd.
4*262e1f6eSChunyan Zhang  *
5*262e1f6eSChunyan Zhang  * This program is free software; you can redistribute it and/or modify it
6*262e1f6eSChunyan Zhang  * under the terms and conditions of the GNU General Public License,
7*262e1f6eSChunyan Zhang  * version 2, as published by the Free Software Foundation.
8*262e1f6eSChunyan Zhang  *
9*262e1f6eSChunyan Zhang  * This program is distributed in the hope it will be useful, but WITHOUT
10*262e1f6eSChunyan Zhang  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11*262e1f6eSChunyan Zhang  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12*262e1f6eSChunyan Zhang  * more details.
13*262e1f6eSChunyan Zhang  *
14*262e1f6eSChunyan Zhang  * STM Ftrace will be registered as a trace_export.
15*262e1f6eSChunyan Zhang  */
16*262e1f6eSChunyan Zhang 
17*262e1f6eSChunyan Zhang #include <linux/module.h>
18*262e1f6eSChunyan Zhang #include <linux/stm.h>
19*262e1f6eSChunyan Zhang #include <linux/trace.h>
20*262e1f6eSChunyan Zhang 
21*262e1f6eSChunyan Zhang #define STM_FTRACE_NR_CHANNELS 1
22*262e1f6eSChunyan Zhang #define STM_FTRACE_CHAN 0
23*262e1f6eSChunyan Zhang 
24*262e1f6eSChunyan Zhang static int stm_ftrace_link(struct stm_source_data *data);
25*262e1f6eSChunyan Zhang static void stm_ftrace_unlink(struct stm_source_data *data);
26*262e1f6eSChunyan Zhang 
27*262e1f6eSChunyan Zhang static struct stm_ftrace {
28*262e1f6eSChunyan Zhang 	struct stm_source_data	data;
29*262e1f6eSChunyan Zhang 	struct trace_export	ftrace;
30*262e1f6eSChunyan Zhang } stm_ftrace = {
31*262e1f6eSChunyan Zhang 	.data	= {
32*262e1f6eSChunyan Zhang 		.name		= "ftrace",
33*262e1f6eSChunyan Zhang 		.nr_chans	= STM_FTRACE_NR_CHANNELS,
34*262e1f6eSChunyan Zhang 		.link		= stm_ftrace_link,
35*262e1f6eSChunyan Zhang 		.unlink		= stm_ftrace_unlink,
36*262e1f6eSChunyan Zhang 	},
37*262e1f6eSChunyan Zhang };
38*262e1f6eSChunyan Zhang 
39*262e1f6eSChunyan Zhang /**
40*262e1f6eSChunyan Zhang  * stm_ftrace_write() - write data to STM via 'stm_ftrace' source
41*262e1f6eSChunyan Zhang  * @buf:	buffer containing the data packet
42*262e1f6eSChunyan Zhang  * @len:	length of the data packet
43*262e1f6eSChunyan Zhang  */
44*262e1f6eSChunyan Zhang static void notrace
45*262e1f6eSChunyan Zhang stm_ftrace_write(const void *buf, unsigned int len)
46*262e1f6eSChunyan Zhang {
47*262e1f6eSChunyan Zhang 	stm_source_write(&stm_ftrace.data, STM_FTRACE_CHAN, buf, len);
48*262e1f6eSChunyan Zhang }
49*262e1f6eSChunyan Zhang 
50*262e1f6eSChunyan Zhang static int stm_ftrace_link(struct stm_source_data *data)
51*262e1f6eSChunyan Zhang {
52*262e1f6eSChunyan Zhang 	struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
53*262e1f6eSChunyan Zhang 
54*262e1f6eSChunyan Zhang 	sf->ftrace.write = stm_ftrace_write;
55*262e1f6eSChunyan Zhang 
56*262e1f6eSChunyan Zhang 	return register_ftrace_export(&sf->ftrace);
57*262e1f6eSChunyan Zhang }
58*262e1f6eSChunyan Zhang 
59*262e1f6eSChunyan Zhang static void stm_ftrace_unlink(struct stm_source_data *data)
60*262e1f6eSChunyan Zhang {
61*262e1f6eSChunyan Zhang 	struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
62*262e1f6eSChunyan Zhang 
63*262e1f6eSChunyan Zhang 	unregister_ftrace_export(&sf->ftrace);
64*262e1f6eSChunyan Zhang }
65*262e1f6eSChunyan Zhang 
66*262e1f6eSChunyan Zhang static int __init stm_ftrace_init(void)
67*262e1f6eSChunyan Zhang {
68*262e1f6eSChunyan Zhang 	int ret;
69*262e1f6eSChunyan Zhang 
70*262e1f6eSChunyan Zhang 	ret = stm_source_register_device(NULL, &stm_ftrace.data);
71*262e1f6eSChunyan Zhang 	if (ret)
72*262e1f6eSChunyan Zhang 		pr_err("Failed to register stm_source - ftrace.\n");
73*262e1f6eSChunyan Zhang 
74*262e1f6eSChunyan Zhang 	return ret;
75*262e1f6eSChunyan Zhang }
76*262e1f6eSChunyan Zhang 
77*262e1f6eSChunyan Zhang static void __exit stm_ftrace_exit(void)
78*262e1f6eSChunyan Zhang {
79*262e1f6eSChunyan Zhang 	stm_source_unregister_device(&stm_ftrace.data);
80*262e1f6eSChunyan Zhang }
81*262e1f6eSChunyan Zhang 
82*262e1f6eSChunyan Zhang module_init(stm_ftrace_init);
83*262e1f6eSChunyan Zhang module_exit(stm_ftrace_exit);
84*262e1f6eSChunyan Zhang 
85*262e1f6eSChunyan Zhang MODULE_LICENSE("GPL v2");
86*262e1f6eSChunyan Zhang MODULE_DESCRIPTION("stm_ftrace driver");
87*262e1f6eSChunyan Zhang MODULE_AUTHOR("Chunyan Zhang <zhang.chunyan@linaro.org>");
88