blob: b9cddc459299e61221b552d4e7152467ad117ddf [file] [log] [blame]
Eric Holmberg6275b602012-11-19 13:05:04 -07001/* arch/arm/mach-msm/smp2p_test_common.h
2 *
3 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#ifndef _ARCH_ARM_MACH_MSM_SMP2P_TEST_COMMON_H_
15#define _ARCH_ARM_MACH_MSM_SMP2P_TEST_COMMON_H_
16
17#include <linux/debugfs.h>
18
19/**
20 * Unit test assertion for logging test cases.
21 *
22 * @a lval
23 * @b rval
24 * @cmp comparison operator
25 *
26 * Assertion fails if (@a cmp @b) is not true which then
27 * logs the function and line number where the error occurred
28 * along with the values of @a and @b.
29 *
30 * Assumes that the following local variables exist:
31 * @s - sequential output file pointer
32 * @failed - set to true if test fails
33 */
34#define UT_ASSERT_INT(a, cmp, b) \
35 { \
36 int a_tmp = (a); \
37 int b_tmp = (b); \
38 if (!((a_tmp)cmp(b_tmp))) { \
39 seq_printf(s, \
40 "%s:%d Fail: " #a "(%d) " #cmp " " #b "(%d)\n", \
41 __func__, __LINE__, \
42 a_tmp, b_tmp); \
43 failed = 1; \
44 break; \
45 } \
46 }
47
48#define UT_ASSERT_PTR(a, cmp, b) \
49 { \
50 void *a_tmp = (a); \
51 void *b_tmp = (b); \
52 if (!((a_tmp)cmp(b_tmp))) { \
53 seq_printf(s, \
54 "%s:%d Fail: " #a "(%p) " #cmp " " #b "(%p)\n", \
55 __func__, __LINE__, \
56 a_tmp, b_tmp); \
57 failed = 1; \
58 break; \
59 } \
60 }
61
62#define UT_ASSERT_UINT(a, cmp, b) \
63 { \
64 unsigned a_tmp = (a); \
65 unsigned b_tmp = (b); \
66 if (!((a_tmp)cmp(b_tmp))) { \
67 seq_printf(s, \
68 "%s:%d Fail: " #a "(%u) " #cmp " " #b "(%u)\n", \
69 __func__, __LINE__, \
70 a_tmp, b_tmp); \
71 failed = 1; \
72 break; \
73 } \
74 }
75
76#define UT_ASSERT_HEX(a, cmp, b) \
77 { \
78 unsigned a_tmp = (a); \
79 unsigned b_tmp = (b); \
80 if (!((a_tmp)cmp(b_tmp))) { \
81 seq_printf(s, \
82 "%s:%d Fail: " #a "(%x) " #cmp " " #b "(%x)\n", \
83 __func__, __LINE__, \
84 a_tmp, b_tmp); \
85 failed = 1; \
86 break; \
87 } \
88 }
89
90/**
91 * In-range unit test assertion for test cases.
92 *
93 * @a lval
94 * @minv Minimum value
95 * @maxv Maximum value
96 *
97 * Assertion fails if @a is not on the exclusive range minv, maxv
98 * ((@a < @minv) or (@a > @maxv)). In the failure case, the macro
99 * logs the function and line number where the error occurred along
100 * with the values of @a and @minv, @maxv.
101 *
102 * Assumes that the following local variables exist:
103 * @s - sequential output file pointer
104 * @failed - set to true if test fails
105 */
106#define UT_ASSERT_INT_IN_RANGE(a, minv, maxv) \
107 { \
108 int a_tmp = (a); \
109 int minv_tmp = (minv); \
110 int maxv_tmp = (maxv); \
111 if (((a_tmp) < (minv_tmp)) || ((a_tmp) > (maxv_tmp))) { \
112 seq_printf(s, \
113 "%s:%d Fail: " #a "(%d) < " #minv "(%d) or " \
114 #a "(%d) > " #maxv "(%d)\n", \
115 __func__, __LINE__, \
116 a_tmp, minv_tmp, a_tmp, maxv_tmp); \
117 failed = 1; \
118 break; \
119 } \
120 }
121
122/* Structure to track state changes for the notifier callback. */
123struct mock_cb_data {
124 bool initialized;
125 spinlock_t lock;
126 struct notifier_block nb;
127
128 /* events */
129 struct completion cb_completion;
130 int cb_count;
131 int event_open;
132 int event_entry_update;
133 struct msm_smp2p_update_notif entry_data;
134};
135
136void smp2p_debug_create(const char *name, void (*show)(struct seq_file *));
137static inline int smp2p_test_notify(struct notifier_block *self,
138 unsigned long event, void *data);
139
140/**
141 * Reset mock callback data to default values.
142 *
143 * @cb: Mock callback data
144 */
145static inline void mock_cb_data_reset(struct mock_cb_data *cb)
146{
147 INIT_COMPLETION(cb->cb_completion);
148 cb->cb_count = 0;
149 cb->event_open = 0;
150 cb->event_entry_update = 0;
151 memset(&cb->entry_data, 0,
152 sizeof(struct msm_smp2p_update_notif));
153}
154
155
156/**
157 * Initialize mock callback data.
158 *
159 * @cb: Mock callback data
160 */
161static inline void mock_cb_data_init(struct mock_cb_data *cb)
162{
163 if (!cb->initialized) {
164 init_completion(&cb->cb_completion);
165 spin_lock_init(&cb->lock);
166 cb->initialized = true;
167 cb->nb.notifier_call = smp2p_test_notify;
168 memset(&cb->entry_data, 0,
169 sizeof(struct msm_smp2p_update_notif));
170 }
171 mock_cb_data_reset(cb);
172}
173
174/**
175 * Notifier function passed into SMP2P for testing.
176 *
177 * @self: Pointer to calling notifier block
178 * @event: Event
179 * @data: Event-specific data
180 * @returns: 0
181 */
182static inline int smp2p_test_notify(struct notifier_block *self,
183 unsigned long event, void *data)
184{
185 struct mock_cb_data *cb_data_ptr;
186 unsigned long flags;
187
188 cb_data_ptr = container_of(self, struct mock_cb_data, nb);
189
190 spin_lock_irqsave(&cb_data_ptr->lock, flags);
191
192 switch (event) {
193 case SMP2P_OPEN:
194 ++cb_data_ptr->event_open;
195 if (data) {
196 cb_data_ptr->entry_data =
197 *(struct msm_smp2p_update_notif *)(data);
198 }
199 break;
200 case SMP2P_ENTRY_UPDATE:
201 ++cb_data_ptr->event_entry_update;
202 if (data) {
203 cb_data_ptr->entry_data =
204 *(struct msm_smp2p_update_notif *)(data);
205 }
206 break;
207 default:
208 pr_err("%s Unknown event\n", __func__);
209 break;
210 }
211
212 ++cb_data_ptr->cb_count;
213 complete(&cb_data_ptr->cb_completion);
214 spin_unlock_irqrestore(&cb_data_ptr->lock, flags);
215 return 0;
216}
217#endif /* _ARCH_ARM_MACH_MSM_SMP2P_TEST_COMMON_H_ */