aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwtracing
diff options
context:
space:
mode:
authorAlexander Shishkin <alexander.shishkin@linux.intel.com>2016-02-15 12:12:04 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-02-20 17:09:14 -0500
commit1192918530381b5cfc0e5da51233fa94f783b221 (patch)
treec0f85d2050633c84eb8c1f11a0c7677f52418bee /drivers/hwtracing
parentbcfdf8afdebe63a2217fa632ae94f8aeecf9126f (diff)
stm class: Add heartbeat stm source device
Heartbeat stm source may have multiple instances (for connecting to different stm devices). Each instance will send a periodic test message over its stm device when it is linked. This can be used for testing stm class framework, stm device drivers or as a heartbeat over the stm link. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hwtracing')
-rw-r--r--drivers/hwtracing/stm/Kconfig11
-rw-r--r--drivers/hwtracing/stm/Makefile2
-rw-r--r--drivers/hwtracing/stm/heartbeat.c130
3 files changed, 143 insertions, 0 deletions
diff --git a/drivers/hwtracing/stm/Kconfig b/drivers/hwtracing/stm/Kconfig
index e0ac75395526..847a39b35307 100644
--- a/drivers/hwtracing/stm/Kconfig
+++ b/drivers/hwtracing/stm/Kconfig
@@ -28,4 +28,15 @@ config STM_SOURCE_CONSOLE
28 If you want to send kernel console messages over STM devices, 28 If you want to send kernel console messages over STM devices,
29 say Y. 29 say Y.
30 30
31config STM_SOURCE_HEARTBEAT
32 tristate "Heartbeat over STM devices"
33 help
34 This is a kernel space trace source that sends periodic
35 heartbeat messages to trace hosts over STM devices. It is
36 also useful for testing stm class drivers and the stm class
37 framework itself.
38
39 If you want to send heartbeat messages over STM devices,
40 say Y.
41
31endif 42endif
diff --git a/drivers/hwtracing/stm/Makefile b/drivers/hwtracing/stm/Makefile
index f9312c38dd7a..a9ce3d487e57 100644
--- a/drivers/hwtracing/stm/Makefile
+++ b/drivers/hwtracing/stm/Makefile
@@ -5,5 +5,7 @@ stm_core-y := core.o policy.o
5obj-$(CONFIG_STM_DUMMY) += dummy_stm.o 5obj-$(CONFIG_STM_DUMMY) += dummy_stm.o
6 6
7obj-$(CONFIG_STM_SOURCE_CONSOLE) += stm_console.o 7obj-$(CONFIG_STM_SOURCE_CONSOLE) += stm_console.o
8obj-$(CONFIG_STM_SOURCE_HEARTBEAT) += stm_heartbeat.o
8 9
9stm_console-y := console.o 10stm_console-y := console.o
11stm_heartbeat-y := heartbeat.o
diff --git a/drivers/hwtracing/stm/heartbeat.c b/drivers/hwtracing/stm/heartbeat.c
new file mode 100644
index 000000000000..0133571b506f
--- /dev/null
+++ b/drivers/hwtracing/stm/heartbeat.c
@@ -0,0 +1,130 @@
1/*
2 * Simple heartbeat STM source driver
3 * Copyright (c) 2016, 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 * Heartbeat STM source will send repetitive messages over STM devices to a
15 * trace host.
16 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/hrtimer.h>
21#include <linux/slab.h>
22#include <linux/stm.h>
23
24#define STM_HEARTBEAT_MAX 32
25
26static int nr_devs = 4;
27static int interval_ms = 10;
28
29module_param(nr_devs, int, 0600);
30module_param(interval_ms, int, 0600);
31
32static struct stm_heartbeat {
33 struct stm_source_data data;
34 struct hrtimer hrtimer;
35 unsigned int active;
36} stm_heartbeat[STM_HEARTBEAT_MAX];
37
38static unsigned int nr_instances;
39
40static const char str[] = "heartbeat stm source driver is here to serve you";
41
42static enum hrtimer_restart stm_heartbeat_hrtimer_handler(struct hrtimer *hr)
43{
44 struct stm_heartbeat *heartbeat = container_of(hr, struct stm_heartbeat,
45 hrtimer);
46
47 stm_source_write(&heartbeat->data, 0, str, sizeof str);
48 if (heartbeat->active)
49 hrtimer_forward_now(hr, ms_to_ktime(interval_ms));
50
51 return heartbeat->active ? HRTIMER_RESTART : HRTIMER_NORESTART;
52}
53
54static int stm_heartbeat_link(struct stm_source_data *data)
55{
56 struct stm_heartbeat *heartbeat =
57 container_of(data, struct stm_heartbeat, data);
58
59 heartbeat->active = 1;
60 hrtimer_start(&heartbeat->hrtimer, ms_to_ktime(interval_ms),
61 HRTIMER_MODE_ABS);
62
63 return 0;
64}
65
66static void stm_heartbeat_unlink(struct stm_source_data *data)
67{
68 struct stm_heartbeat *heartbeat =
69 container_of(data, struct stm_heartbeat, data);
70
71 heartbeat->active = 0;
72 hrtimer_cancel(&heartbeat->hrtimer);
73}
74
75static int stm_heartbeat_init(void)
76{
77 int i, ret = -ENOMEM, __nr_instances = ACCESS_ONCE(nr_devs);
78
79 if (__nr_instances < 0 || __nr_instances > STM_HEARTBEAT_MAX)
80 return -EINVAL;
81
82 for (i = 0; i < __nr_instances; i++) {
83 stm_heartbeat[i].data.name =
84 kasprintf(GFP_KERNEL, "heartbeat.%d", i);
85 if (!stm_heartbeat[i].data.name)
86 goto fail_unregister;
87
88 stm_heartbeat[i].data.nr_chans = 1;
89 stm_heartbeat[i].data.link = stm_heartbeat_link;
90 stm_heartbeat[i].data.unlink = stm_heartbeat_unlink;
91 hrtimer_init(&stm_heartbeat[i].hrtimer, CLOCK_MONOTONIC,
92 HRTIMER_MODE_ABS);
93 stm_heartbeat[i].hrtimer.function =
94 stm_heartbeat_hrtimer_handler;
95
96 ret = stm_source_register_device(NULL, &stm_heartbeat[i].data);
97 if (ret)
98 goto fail_free;
99 }
100
101 nr_instances = __nr_instances;
102
103 return 0;
104
105fail_unregister:
106 for (i--; i >= 0; i--) {
107 stm_source_unregister_device(&stm_heartbeat[i].data);
108fail_free:
109 kfree(stm_heartbeat[i].data.name);
110 }
111
112 return ret;
113}
114
115static void stm_heartbeat_exit(void)
116{
117 int i;
118
119 for (i = 0; i < nr_instances; i++) {
120 stm_source_unregister_device(&stm_heartbeat[i].data);
121 kfree(stm_heartbeat[i].data.name);
122 }
123}
124
125module_init(stm_heartbeat_init);
126module_exit(stm_heartbeat_exit);
127
128MODULE_LICENSE("GPL v2");
129MODULE_DESCRIPTION("stm_heartbeat driver");
130MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>");