Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Simple kernel driver to link kernel Ftrace and an STM device
0004  * Copyright (c) 2016, Linaro Ltd.
0005  *
0006  * STM Ftrace will be registered as a trace_export.
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/stm.h>
0011 #include <linux/trace.h>
0012 
0013 #define STM_FTRACE_NR_CHANNELS 1
0014 #define STM_FTRACE_CHAN 0
0015 
0016 static int stm_ftrace_link(struct stm_source_data *data);
0017 static void stm_ftrace_unlink(struct stm_source_data *data);
0018 
0019 static struct stm_ftrace {
0020     struct stm_source_data  data;
0021     struct trace_export ftrace;
0022 } stm_ftrace = {
0023     .data   = {
0024         .name       = "ftrace",
0025         .nr_chans   = STM_FTRACE_NR_CHANNELS,
0026         .link       = stm_ftrace_link,
0027         .unlink     = stm_ftrace_unlink,
0028     },
0029 };
0030 
0031 /**
0032  * stm_ftrace_write() - write data to STM via 'stm_ftrace' source
0033  * @buf:    buffer containing the data packet
0034  * @len:    length of the data packet
0035  */
0036 static void notrace
0037 stm_ftrace_write(struct trace_export *export, const void *buf, unsigned int len)
0038 {
0039     struct stm_ftrace *stm = container_of(export, struct stm_ftrace, ftrace);
0040     /* This is called from trace system with preemption disabled */
0041     unsigned int cpu = smp_processor_id();
0042 
0043     stm_source_write(&stm->data, STM_FTRACE_CHAN + cpu, buf, len);
0044 }
0045 
0046 static int stm_ftrace_link(struct stm_source_data *data)
0047 {
0048     struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
0049 
0050     sf->ftrace.write = stm_ftrace_write;
0051     sf->ftrace.flags = TRACE_EXPORT_FUNCTION | TRACE_EXPORT_EVENT
0052             | TRACE_EXPORT_MARKER;
0053 
0054     return register_ftrace_export(&sf->ftrace);
0055 }
0056 
0057 static void stm_ftrace_unlink(struct stm_source_data *data)
0058 {
0059     struct stm_ftrace *sf = container_of(data, struct stm_ftrace, data);
0060 
0061     unregister_ftrace_export(&sf->ftrace);
0062 }
0063 
0064 static int __init stm_ftrace_init(void)
0065 {
0066     int ret;
0067 
0068     stm_ftrace.data.nr_chans = roundup_pow_of_two(num_possible_cpus());
0069     ret = stm_source_register_device(NULL, &stm_ftrace.data);
0070     if (ret)
0071         pr_err("Failed to register stm_source - ftrace.\n");
0072 
0073     return ret;
0074 }
0075 
0076 static void __exit stm_ftrace_exit(void)
0077 {
0078     stm_source_unregister_device(&stm_ftrace.data);
0079 }
0080 
0081 module_init(stm_ftrace_init);
0082 module_exit(stm_ftrace_exit);
0083 
0084 MODULE_LICENSE("GPL v2");
0085 MODULE_DESCRIPTION("stm_ftrace driver");
0086 MODULE_AUTHOR("Chunyan Zhang <zhang.chunyan@linaro.org>");