Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * A dummy STM device for stm/stm_source class testing.
0004  * Copyright (c) 2014, Intel Corporation.
0005  *
0006  * STM class implements generic infrastructure for  System Trace Module devices
0007  * as defined in MIPI STPv2 specification.
0008  */
0009 
0010 #undef DEBUG
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/slab.h>
0014 #include <linux/stm.h>
0015 #include <uapi/linux/stm.h>
0016 
0017 static ssize_t notrace
0018 dummy_stm_packet(struct stm_data *stm_data, unsigned int master,
0019          unsigned int channel, unsigned int packet, unsigned int flags,
0020          unsigned int size, const unsigned char *payload)
0021 {
0022 #ifdef DEBUG
0023     u64 pl = 0;
0024 
0025     if (payload)
0026         pl = *(u64 *)payload;
0027 
0028     if (size < 8)
0029         pl &= (1ull << (size * 8)) - 1;
0030     trace_printk("[%u:%u] [pkt: %x/%x] (%llx)\n", master, channel,
0031              packet, size, pl);
0032 #endif
0033     return size;
0034 }
0035 
0036 #define DUMMY_STM_MAX 32
0037 
0038 static struct stm_data dummy_stm[DUMMY_STM_MAX];
0039 
0040 static int nr_dummies = 4;
0041 
0042 module_param(nr_dummies, int, 0400);
0043 
0044 static unsigned int fail_mode;
0045 
0046 module_param(fail_mode, int, 0600);
0047 
0048 static unsigned int master_min;
0049 
0050 module_param(master_min, int, 0400);
0051 
0052 static unsigned int master_max = STP_MASTER_MAX;
0053 
0054 module_param(master_max, int, 0400);
0055 
0056 static unsigned int nr_channels = STP_CHANNEL_MAX;
0057 
0058 module_param(nr_channels, int, 0400);
0059 
0060 static int dummy_stm_link(struct stm_data *data, unsigned int master,
0061               unsigned int channel)
0062 {
0063     if (fail_mode && (channel & fail_mode))
0064         return -EINVAL;
0065 
0066     return 0;
0067 }
0068 
0069 static int dummy_stm_init(void)
0070 {
0071     int i, ret = -ENOMEM;
0072 
0073     if (nr_dummies < 0 || nr_dummies > DUMMY_STM_MAX)
0074         return -EINVAL;
0075 
0076     if (master_min > master_max ||
0077         master_max > STP_MASTER_MAX ||
0078         nr_channels > STP_CHANNEL_MAX)
0079         return -EINVAL;
0080 
0081     for (i = 0; i < nr_dummies; i++) {
0082         dummy_stm[i].name = kasprintf(GFP_KERNEL, "dummy_stm.%d", i);
0083         if (!dummy_stm[i].name)
0084             goto fail_unregister;
0085 
0086         dummy_stm[i].sw_start       = master_min;
0087         dummy_stm[i].sw_end     = master_max;
0088         dummy_stm[i].sw_nchannels   = nr_channels;
0089         dummy_stm[i].packet     = dummy_stm_packet;
0090         dummy_stm[i].link       = dummy_stm_link;
0091 
0092         ret = stm_register_device(NULL, &dummy_stm[i], THIS_MODULE);
0093         if (ret)
0094             goto fail_free;
0095     }
0096 
0097     return 0;
0098 
0099 fail_unregister:
0100     for (i--; i >= 0; i--) {
0101         stm_unregister_device(&dummy_stm[i]);
0102 fail_free:
0103         kfree(dummy_stm[i].name);
0104     }
0105 
0106     return ret;
0107 
0108 }
0109 
0110 static void dummy_stm_exit(void)
0111 {
0112     int i;
0113 
0114     for (i = 0; i < nr_dummies; i++) {
0115         stm_unregister_device(&dummy_stm[i]);
0116         kfree(dummy_stm[i].name);
0117     }
0118 }
0119 
0120 module_init(dummy_stm_init);
0121 module_exit(dummy_stm_exit);
0122 
0123 MODULE_LICENSE("GPL v2");
0124 MODULE_DESCRIPTION("dummy_stm device");
0125 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>");