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