xref: /linux/drivers/hwtracing/stm/dummy_stm.c (revision 9ea393d8d8377b6da8ee25c6a114ec24c0687c7c)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * A dummy STM device for stm/stm_source class testing.
4  * Copyright (c) 2014, Intel Corporation.
5  *
6  * STM class implements generic infrastructure for  System Trace Module devices
7  * as defined in MIPI STPv2 specification.
8  */
9 
10 #undef DEBUG
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/stm.h>
15 
16 static ssize_t notrace
17 dummy_stm_packet(struct stm_data *stm_data, unsigned int master,
18 		 unsigned int channel, unsigned int packet, unsigned int flags,
19 		 unsigned int size, const unsigned char *payload)
20 {
21 #ifdef DEBUG
22 	u64 pl = 0;
23 
24 	if (payload)
25 		pl = *(u64 *)payload;
26 
27 	if (size < 8)
28 		pl &= (1ull << (size * 8)) - 1;
29 	trace_printk("[%u:%u] [pkt: %x/%x] (%llx)\n", master, channel,
30 		     packet, size, pl);
31 #endif
32 	return size;
33 }
34 
35 #define DUMMY_STM_MAX 32
36 
37 static struct stm_data dummy_stm[DUMMY_STM_MAX];
38 
39 static int nr_dummies = 4;
40 
41 module_param(nr_dummies, int, 0400);
42 
43 static unsigned int fail_mode;
44 
45 module_param(fail_mode, int, 0600);
46 
47 static int dummy_stm_link(struct stm_data *data, unsigned int master,
48 			  unsigned int channel)
49 {
50 	if (fail_mode && (channel & fail_mode))
51 		return -EINVAL;
52 
53 	return 0;
54 }
55 
56 static int dummy_stm_init(void)
57 {
58 	int i, ret = -ENOMEM;
59 
60 	if (nr_dummies < 0 || nr_dummies > DUMMY_STM_MAX)
61 		return -EINVAL;
62 
63 	for (i = 0; i < nr_dummies; i++) {
64 		dummy_stm[i].name = kasprintf(GFP_KERNEL, "dummy_stm.%d", i);
65 		if (!dummy_stm[i].name)
66 			goto fail_unregister;
67 
68 		dummy_stm[i].sw_start		= 0x0000;
69 		dummy_stm[i].sw_end		= 0xffff;
70 		dummy_stm[i].sw_nchannels	= 0xffff;
71 		dummy_stm[i].packet		= dummy_stm_packet;
72 		dummy_stm[i].link		= dummy_stm_link;
73 
74 		ret = stm_register_device(NULL, &dummy_stm[i], THIS_MODULE);
75 		if (ret)
76 			goto fail_free;
77 	}
78 
79 	return 0;
80 
81 fail_unregister:
82 	for (i--; i >= 0; i--) {
83 		stm_unregister_device(&dummy_stm[i]);
84 fail_free:
85 		kfree(dummy_stm[i].name);
86 	}
87 
88 	return ret;
89 
90 }
91 
92 static void dummy_stm_exit(void)
93 {
94 	int i;
95 
96 	for (i = 0; i < nr_dummies; i++) {
97 		stm_unregister_device(&dummy_stm[i]);
98 		kfree(dummy_stm[i].name);
99 	}
100 }
101 
102 module_init(dummy_stm_init);
103 module_exit(dummy_stm_exit);
104 
105 MODULE_LICENSE("GPL v2");
106 MODULE_DESCRIPTION("dummy_stm device");
107 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>");
108