linux/drivers/hwtracing/stm/dummy_stm.c
<<
>>
Prefs
   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
  24static ssize_t
  25dummy_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
  45static struct stm_data dummy_stm[DUMMY_STM_MAX];
  46
  47static int nr_dummies = 4;
  48
  49module_param(nr_dummies, int, 0600);
  50
  51static unsigned int dummy_stm_nr;
  52
  53static unsigned int fail_mode;
  54
  55module_param(fail_mode, int, 0600);
  56
  57static int dummy_stm_link(struct stm_data *data, unsigned int master,
  58                          unsigned int channel)
  59{
  60        if (fail_mode && (channel & fail_mode))
  61                return -EINVAL;
  62
  63        return 0;
  64}
  65
  66static int dummy_stm_init(void)
  67{
  68        int i, ret = -ENOMEM, __nr_dummies = ACCESS_ONCE(nr_dummies);
  69
  70        if (__nr_dummies < 0 || __nr_dummies > DUMMY_STM_MAX)
  71                return -EINVAL;
  72
  73        for (i = 0; i < __nr_dummies; i++) {
  74                dummy_stm[i].name = kasprintf(GFP_KERNEL, "dummy_stm.%d", i);
  75                if (!dummy_stm[i].name)
  76                        goto fail_unregister;
  77
  78                dummy_stm[i].sw_start           = 0x0000;
  79                dummy_stm[i].sw_end             = 0xffff;
  80                dummy_stm[i].sw_nchannels       = 0xffff;
  81                dummy_stm[i].packet             = dummy_stm_packet;
  82                dummy_stm[i].link               = dummy_stm_link;
  83
  84                ret = stm_register_device(NULL, &dummy_stm[i], THIS_MODULE);
  85                if (ret)
  86                        goto fail_free;
  87        }
  88
  89        dummy_stm_nr = __nr_dummies;
  90
  91        return 0;
  92
  93fail_unregister:
  94        for (i--; i >= 0; i--) {
  95                stm_unregister_device(&dummy_stm[i]);
  96fail_free:
  97                kfree(dummy_stm[i].name);
  98        }
  99
 100        return ret;
 101
 102}
 103
 104static void dummy_stm_exit(void)
 105{
 106        int i;
 107
 108        for (i = 0; i < dummy_stm_nr; i++) {
 109                stm_unregister_device(&dummy_stm[i]);
 110                kfree(dummy_stm[i].name);
 111        }
 112}
 113
 114module_init(dummy_stm_init);
 115module_exit(dummy_stm_exit);
 116
 117MODULE_LICENSE("GPL v2");
 118MODULE_DESCRIPTION("dummy_stm device");
 119MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>");
 120