1 /* 2 * A dummy STM device for stm/stm_source class testing. 3 * Copyright (c) 2014, Intel Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * STM class implements generic infrastructure for System Trace Module devices 15 * as defined in MIPI STPv2 specification. 16 */ 17 18 #undef DEBUG 19 #include <linux/kernel.h> 20 #include <linux/module.h> 21 #include <linux/slab.h> 22 #include <linux/stm.h> 23 24 static ssize_t notrace 25 dummy_stm_packet(struct stm_data *stm_data, unsigned int master, 26 unsigned int channel, unsigned int packet, unsigned int flags, 27 unsigned int size, const unsigned char *payload) 28 { 29 #ifdef DEBUG 30 u64 pl = 0; 31 32 if (payload) 33 pl = *(u64 *)payload; 34 35 if (size < 8) 36 pl &= (1ull << (size * 8)) - 1; 37 trace_printk("[%u:%u] [pkt: %x/%x] (%llx)\n", master, channel, 38 packet, size, pl); 39 #endif 40 return size; 41 } 42 43 #define DUMMY_STM_MAX 32 44 45 static struct stm_data dummy_stm[DUMMY_STM_MAX]; 46 47 static int nr_dummies = 4; 48 49 module_param(nr_dummies, int, 0400); 50 51 static unsigned int fail_mode; 52 53 module_param(fail_mode, int, 0600); 54 55 static int dummy_stm_link(struct stm_data *data, unsigned int master, 56 unsigned int channel) 57 { 58 if (fail_mode && (channel & fail_mode)) 59 return -EINVAL; 60 61 return 0; 62 } 63 64 static int dummy_stm_init(void) 65 { 66 int i, ret = -ENOMEM; 67 68 if (nr_dummies < 0 || nr_dummies > DUMMY_STM_MAX) 69 return -EINVAL; 70 71 for (i = 0; i < nr_dummies; i++) { 72 dummy_stm[i].name = kasprintf(GFP_KERNEL, "dummy_stm.%d", i); 73 if (!dummy_stm[i].name) 74 goto fail_unregister; 75 76 dummy_stm[i].sw_start = 0x0000; 77 dummy_stm[i].sw_end = 0xffff; 78 dummy_stm[i].sw_nchannels = 0xffff; 79 dummy_stm[i].packet = dummy_stm_packet; 80 dummy_stm[i].link = dummy_stm_link; 81 82 ret = stm_register_device(NULL, &dummy_stm[i], THIS_MODULE); 83 if (ret) 84 goto fail_free; 85 } 86 87 return 0; 88 89 fail_unregister: 90 for (i--; i >= 0; i--) { 91 stm_unregister_device(&dummy_stm[i]); 92 fail_free: 93 kfree(dummy_stm[i].name); 94 } 95 96 return ret; 97 98 } 99 100 static void dummy_stm_exit(void) 101 { 102 int i; 103 104 for (i = 0; i < nr_dummies; i++) { 105 stm_unregister_device(&dummy_stm[i]); 106 kfree(dummy_stm[i].name); 107 } 108 } 109 110 module_init(dummy_stm_init); 111 module_exit(dummy_stm_exit); 112 113 MODULE_LICENSE("GPL v2"); 114 MODULE_DESCRIPTION("dummy_stm device"); 115 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>"); 116