blob: 2f86df4b7ff692260dbaa2959322e321a9e0f873 [file] [log] [blame]
Eric Holmberg6275b602012-11-19 13:05:04 -07001/* arch/arm/mach-msm/smp2p_test.c
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#include <linux/debugfs.h>
15#include <linux/ctype.h>
16#include <linux/jiffies.h>
17#include <linux/delay.h>
18#include <linux/completion.h>
Eric Holmberg7aadc772013-09-16 16:52:51 -060019#include <mach/subsystem_restart.h>
Eric Holmberg6275b602012-11-19 13:05:04 -070020#include "smp2p_private.h"
21#include "smp2p_test_common.h"
22
23/**
24 * smp2p_ut_local_basic - Basic sanity test using local loopback.
25 *
26 * @s: pointer to output file
27 *
28 * This test simulates a simple write and read
29 * when remote processor does not exist.
30 */
31static void smp2p_ut_local_basic(struct seq_file *s)
32{
33 int failed = 0;
34 struct msm_smp2p_out *smp2p_obj;
35 struct msm_smp2p_remote_mock *rmp = NULL;
36 int ret;
37 uint32_t test_request;
38 uint32_t test_response = 0;
39 static struct mock_cb_data cb_data;
40
41 seq_printf(s, "Running %s\n", __func__);
42 mock_cb_data_init(&cb_data);
43 do {
44 /* initialize mock edge and start opening */
45 ret = smp2p_reset_mock_edge();
46 UT_ASSERT_INT(ret, ==, 0);
47
48 rmp = msm_smp2p_get_remote_mock();
49 UT_ASSERT_PTR(rmp, !=, NULL);
50
51 rmp->rx_interrupt_count = 0;
52 memset(&rmp->remote_item, 0,
53 sizeof(struct smp2p_smem_item));
54
55 msm_smp2p_set_remote_mock_exists(false);
56
57 ret = msm_smp2p_out_open(SMP2P_REMOTE_MOCK_PROC, "smp2p",
58 &cb_data.nb, &smp2p_obj);
59 UT_ASSERT_INT(ret, ==, 0);
60
61 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
62 UT_ASSERT_INT(cb_data.cb_count, ==, 0);
63 rmp->rx_interrupt_count = 0;
64
65 /* simulate response from remote side */
66 rmp->remote_item.header.magic = SMP2P_MAGIC;
67 SMP2P_SET_LOCAL_PID(
68 rmp->remote_item.header.rem_loc_proc_id,
69 SMP2P_REMOTE_MOCK_PROC);
70 SMP2P_SET_REMOTE_PID(
71 rmp->remote_item.header.rem_loc_proc_id,
72 SMP2P_APPS_PROC);
73 SMP2P_SET_VERSION(
74 rmp->remote_item.header.feature_version, 1);
75 SMP2P_SET_FEATURES(
76 rmp->remote_item.header.feature_version, 0);
77 SMP2P_SET_ENT_TOTAL(
78 rmp->remote_item.header.valid_total_ent, SMP2P_MAX_ENTRY);
79 SMP2P_SET_ENT_VALID(
80 rmp->remote_item.header.valid_total_ent, 0);
Eric Holmberg7aadc772013-09-16 16:52:51 -060081 rmp->remote_item.header.flags = 0x0;
Eric Holmberg6275b602012-11-19 13:05:04 -070082 msm_smp2p_set_remote_mock_exists(true);
83 rmp->tx_interrupt();
84
85 /* verify port was opened */
86 UT_ASSERT_INT(
87 (int)wait_for_completion_timeout(
88 &cb_data.cb_completion, HZ / 2), >, 0);
89 UT_ASSERT_INT(cb_data.cb_count, ==, 1);
90 UT_ASSERT_INT(cb_data.event_open, ==, 1);
91 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 2);
92
93 /* do write (test outbound entries) */
94 rmp->rx_interrupt_count = 0;
95 test_request = 0xC0DE;
96 ret = msm_smp2p_out_write(smp2p_obj, test_request);
97 UT_ASSERT_INT(ret, ==, 0);
98 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
99
100 /* do read (test inbound entries) */
101 ret = msm_smp2p_out_read(smp2p_obj, &test_response);
102 UT_ASSERT_INT(ret, ==, 0);
103 UT_ASSERT_INT(test_request, ==, test_response);
104
105 ret = msm_smp2p_out_close(&smp2p_obj);
106 UT_ASSERT_INT(ret, ==, 0);
107 UT_ASSERT_PTR(smp2p_obj, ==, 0);
108
109 seq_printf(s, "\tOK\n");
110 } while (0);
111
112 if (failed) {
113 pr_err("%s: Failed\n", __func__);
114 seq_printf(s, "\tFailed\n");
115 (void)msm_smp2p_out_close(&smp2p_obj);
116 }
117}
118
119/**
120 * smp2p_ut_local_late_open - Verify post-negotiation opening.
121 *
122 * @s: pointer to output file
123 *
124 * Verify entry creation for opening entries after negotiation is complete.
125 */
126static void smp2p_ut_local_late_open(struct seq_file *s)
127{
128 int failed = 0;
129 struct msm_smp2p_out *smp2p_obj;
130 struct msm_smp2p_remote_mock *rmp = NULL;
131 int ret;
132 uint32_t test_request;
133 uint32_t test_response = 0;
134 static struct mock_cb_data cb_data;
135
136 seq_printf(s, "Running %s\n", __func__);
137 mock_cb_data_init(&cb_data);
138 do {
139 /* initialize mock edge */
140 ret = smp2p_reset_mock_edge();
141 UT_ASSERT_INT(ret, ==, 0);
142
143 rmp = msm_smp2p_get_remote_mock();
144 UT_ASSERT_PTR(rmp, !=, NULL);
145
146 rmp->rx_interrupt_count = 0;
147 memset(&rmp->remote_item, 0,
148 sizeof(struct smp2p_smem_item));
149 rmp->remote_item.header.magic = SMP2P_MAGIC;
150 SMP2P_SET_LOCAL_PID(
151 rmp->remote_item.header.rem_loc_proc_id,
152 SMP2P_REMOTE_MOCK_PROC);
153 SMP2P_SET_REMOTE_PID(
154 rmp->remote_item.header.rem_loc_proc_id,
155 SMP2P_APPS_PROC);
156 SMP2P_SET_VERSION(
157 rmp->remote_item.header.feature_version, 1);
158 SMP2P_SET_FEATURES(
159 rmp->remote_item.header.feature_version, 0);
160 SMP2P_SET_ENT_TOTAL(
161 rmp->remote_item.header.valid_total_ent,
162 SMP2P_MAX_ENTRY);
163 SMP2P_SET_ENT_VALID(
164 rmp->remote_item.header.valid_total_ent, 0);
Eric Holmberg7aadc772013-09-16 16:52:51 -0600165 rmp->remote_item.header.flags = 0x0;
Eric Holmberg6275b602012-11-19 13:05:04 -0700166
167 msm_smp2p_set_remote_mock_exists(true);
168
169 ret = msm_smp2p_out_open(SMP2P_REMOTE_MOCK_PROC, "smp2p",
170 &cb_data.nb, &smp2p_obj);
171 UT_ASSERT_INT(ret, ==, 0);
172
173 /* verify port was opened */
174 UT_ASSERT_INT(
175 (int)wait_for_completion_timeout(
176 &cb_data.cb_completion, HZ / 2),
177 >, 0);
178 UT_ASSERT_INT(cb_data.cb_count, ==, 1);
179 UT_ASSERT_INT(cb_data.event_open, ==, 1);
180 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 2);
181
182 /* do write (test outbound entries) */
183 rmp->rx_interrupt_count = 0;
184 test_request = 0xC0DE;
185 ret = msm_smp2p_out_write(smp2p_obj, test_request);
186 UT_ASSERT_INT(ret, ==, 0);
187 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
188
189 /* do read (test inbound entries) */
190 ret = msm_smp2p_out_read(smp2p_obj, &test_response);
191 UT_ASSERT_INT(ret, ==, 0);
192 UT_ASSERT_INT(test_request, ==, test_response);
193
194 ret = msm_smp2p_out_close(&smp2p_obj);
195 UT_ASSERT_INT(ret, ==, 0);
196 UT_ASSERT_PTR(smp2p_obj, ==, 0);
197
198 seq_printf(s, "\tOK\n");
199 } while (0);
200
201 if (failed) {
202 pr_err("%s: Failed\n", __func__);
203 seq_printf(s, "\tFailed\n");
204 (void)msm_smp2p_out_close(&smp2p_obj);
205 }
206}
207
208/**
209 * smp2p_ut_local_early_open - Verify pre-negotiation opening.
210 *
211 * @s: pointer to output file
212 *
213 * Verify entry creation for opening entries before negotiation is complete.
214 */
215static void smp2p_ut_local_early_open(struct seq_file *s)
216{
217 int failed = 0;
218 struct msm_smp2p_out *smp2p_obj;
219 struct msm_smp2p_remote_mock *rmp = NULL;
220 struct smp2p_smem *outbound_item;
221 int negotiation_state;
222 int ret;
223 uint32_t test_request;
224 uint32_t test_response = 0;
225 static struct mock_cb_data cb_data;
226
227 seq_printf(s, "Running %s\n", __func__);
228 mock_cb_data_init(&cb_data);
229 do {
230 /* initialize mock edge, but don't enable, yet */
231 ret = smp2p_reset_mock_edge();
232 UT_ASSERT_INT(ret, ==, 0);
233
234 rmp = msm_smp2p_get_remote_mock();
235 UT_ASSERT_PTR(rmp, !=, NULL);
236
237 rmp->rx_interrupt_count = 0;
238 memset(&rmp->remote_item, 0,
239 sizeof(struct smp2p_smem_item));
240 rmp->remote_item.header.magic = SMP2P_MAGIC;
241 SMP2P_SET_LOCAL_PID(
242 rmp->remote_item.header.rem_loc_proc_id,
243 SMP2P_REMOTE_MOCK_PROC);
244 SMP2P_SET_REMOTE_PID(
245 rmp->remote_item.header.rem_loc_proc_id,
246 SMP2P_APPS_PROC);
247 SMP2P_SET_VERSION(
248 rmp->remote_item.header.feature_version, 1);
249 SMP2P_SET_FEATURES(
250 rmp->remote_item.header.feature_version, 0);
251 SMP2P_SET_ENT_TOTAL(
252 rmp->remote_item.header.valid_total_ent, SMP2P_MAX_ENTRY);
253 SMP2P_SET_ENT_VALID(
254 rmp->remote_item.header.valid_total_ent, 0);
Eric Holmberg7aadc772013-09-16 16:52:51 -0600255 rmp->remote_item.header.flags = 0x0;
Eric Holmberg6275b602012-11-19 13:05:04 -0700256
257 msm_smp2p_set_remote_mock_exists(false);
258 UT_ASSERT_PTR(NULL, ==,
259 smp2p_get_in_item(SMP2P_REMOTE_MOCK_PROC));
260
261 /* initiate open, but verify it doesn't complete */
262 ret = msm_smp2p_out_open(SMP2P_REMOTE_MOCK_PROC, "smp2p",
263 &cb_data.nb, &smp2p_obj);
264 UT_ASSERT_INT(ret, ==, 0);
265
266 UT_ASSERT_INT(
267 (int)wait_for_completion_timeout(
268 &cb_data.cb_completion, HZ / 8),
269 ==, 0);
270 UT_ASSERT_INT(cb_data.cb_count, ==, 0);
271 UT_ASSERT_INT(cb_data.event_open, ==, 0);
272 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
273
274 outbound_item = smp2p_get_out_item(SMP2P_REMOTE_MOCK_PROC,
275 &negotiation_state);
276 UT_ASSERT_PTR(outbound_item, !=, NULL);
277 UT_ASSERT_INT(negotiation_state, ==, SMP2P_EDGE_STATE_OPENING);
278 UT_ASSERT_INT(0, ==,
279 SMP2P_GET_ENT_VALID(outbound_item->valid_total_ent));
280
281 /* verify that read/write don't work yet */
282 rmp->rx_interrupt_count = 0;
283 test_request = 0x0;
284 ret = msm_smp2p_out_write(smp2p_obj, test_request);
285 UT_ASSERT_INT(ret, ==, -ENODEV);
286 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 0);
287
288 ret = msm_smp2p_out_read(smp2p_obj, &test_response);
289 UT_ASSERT_INT(ret, ==, -ENODEV);
290
291 /* allocate remote entry and verify open */
292 msm_smp2p_set_remote_mock_exists(true);
293 rmp->tx_interrupt();
294
295 UT_ASSERT_INT(
296 (int)wait_for_completion_timeout(
297 &cb_data.cb_completion, HZ / 2),
298 >, 0);
299 UT_ASSERT_INT(cb_data.cb_count, ==, 1);
300 UT_ASSERT_INT(cb_data.event_open, ==, 1);
301 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 2);
302
303 /* do write (test outbound entries) */
304 rmp->rx_interrupt_count = 0;
305 test_request = 0xC0DE;
306 ret = msm_smp2p_out_write(smp2p_obj, test_request);
307 UT_ASSERT_INT(ret, ==, 0);
308 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
309
310 /* do read (test inbound entries) */
311 ret = msm_smp2p_out_read(smp2p_obj, &test_response);
312 UT_ASSERT_INT(ret, ==, 0);
313 UT_ASSERT_INT(test_request, ==, test_response);
314
315 ret = msm_smp2p_out_close(&smp2p_obj);
316 UT_ASSERT_INT(ret, ==, 0);
317 UT_ASSERT_PTR(smp2p_obj, ==, 0);
318
319 seq_printf(s, "\tOK\n");
320 } while (0);
321
322 if (failed) {
323 pr_err("%s: Failed\n", __func__);
324 seq_printf(s, "\tFailed\n");
325 (void)msm_smp2p_out_close(&smp2p_obj);
326 }
327}
328
329/**
330 * smp2p_ut_mock_loopback - Exercise the remote loopback using remote mock.
331 *
332 * @s: pointer to output file
333 *
334 * This test exercises the remote loopback code using
335 * remote mock object. The remote mock object simulates the remote
336 * processor sending remote loopback commands to the local processor.
337 */
338static void smp2p_ut_mock_loopback(struct seq_file *s)
339{
340 int failed = 0;
341 struct msm_smp2p_remote_mock *rmp = NULL;
342 int ret;
343 uint32_t test_request = 0;
344 uint32_t test_response = 0;
345 struct msm_smp2p_out *local;
346
347 seq_printf(s, "Running %s\n", __func__);
348 do {
349 /* Initialize the mock edge */
350 ret = smp2p_reset_mock_edge();
351 UT_ASSERT_INT(ret, ==, 0);
352
353 rmp = msm_smp2p_get_remote_mock();
354 UT_ASSERT_PTR(rmp, !=, NULL);
355
356 memset(&rmp->remote_item, 0,
357 sizeof(struct smp2p_smem_item));
358 rmp->remote_item.header.magic = SMP2P_MAGIC;
359 SMP2P_SET_LOCAL_PID(
360 rmp->remote_item.header.rem_loc_proc_id,
361 SMP2P_REMOTE_MOCK_PROC);
362 SMP2P_SET_REMOTE_PID(
363 rmp->remote_item.header.rem_loc_proc_id,
364 SMP2P_APPS_PROC);
365 SMP2P_SET_VERSION(
366 rmp->remote_item.header.feature_version, 1);
367 SMP2P_SET_FEATURES(
368 rmp->remote_item.header.feature_version, 0);
369 SMP2P_SET_ENT_TOTAL(
370 rmp->remote_item.header.valid_total_ent, SMP2P_MAX_ENTRY);
371 SMP2P_SET_ENT_VALID(
372 rmp->remote_item.header.valid_total_ent, 1);
Eric Holmberg7aadc772013-09-16 16:52:51 -0600373 rmp->remote_item.header.flags = 0x0;
Eric Holmberg6275b602012-11-19 13:05:04 -0700374 msm_smp2p_set_remote_mock_exists(true);
375
376 /* Create test entry and attach loopback server */
377 rmp->rx_interrupt_count = 0;
378 INIT_COMPLETION(rmp->cb_completion);
379 strlcpy(rmp->remote_item.entries[0].name, "smp2p",
380 SMP2P_MAX_ENTRY_NAME);
381 rmp->remote_item.entries[0].entry = 0;
382 rmp->tx_interrupt();
383
384 local = msm_smp2p_init_rmt_lpb_proc(SMP2P_REMOTE_MOCK_PROC);
385 UT_ASSERT_INT(
386 (int)wait_for_completion_timeout(
387 &rmp->cb_completion, HZ / 2),
388 >, 0);
389 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 2);
390
391 /* Send Echo Command */
392 rmp->rx_interrupt_count = 0;
393 INIT_COMPLETION(rmp->cb_completion);
394 SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
395 SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_ECHO);
396 SMP2P_SET_RMT_DATA(test_request, 10);
397 rmp->remote_item.entries[0].entry = test_request;
398 rmp->tx_interrupt();
399 UT_ASSERT_INT(
400 (int)wait_for_completion_timeout(
401 &rmp->cb_completion, HZ / 2),
402 >, 0);
403
404 /* Verify Echo Response */
405 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
406 ret = msm_smp2p_out_read(local,
407 &test_response);
408 UT_ASSERT_INT(ret, ==, 0);
409 test_response = SMP2P_GET_RMT_DATA(test_response);
410 UT_ASSERT_INT(test_response, ==, 10);
411
412 /* Send PINGPONG command */
413 test_request = 0;
414 test_response = 0;
415 rmp->rx_interrupt_count = 0;
416 INIT_COMPLETION(rmp->cb_completion);
417 SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
418 SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_PINGPONG);
419 SMP2P_SET_RMT_DATA(test_request, 10);
420 rmp->remote_item.entries[0].entry = test_request;
421 rmp->tx_interrupt();
422 UT_ASSERT_INT(
423 (int)wait_for_completion_timeout(
424 &rmp->cb_completion, HZ / 2),
425 >, 0);
426
427 /* Verify PINGPONG Response */
428 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
429 ret = msm_smp2p_out_read(local, &test_response);
430 UT_ASSERT_INT(ret, ==, 0);
431 test_response = SMP2P_GET_RMT_DATA(test_response);
432 UT_ASSERT_INT(test_response, ==, 9);
433
434 /* Send CLEARALL command */
435 test_request = 0;
436 test_response = 0;
437 rmp->rx_interrupt_count = 0;
438 INIT_COMPLETION(rmp->cb_completion);
439 SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
440 SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_CLEARALL);
441 SMP2P_SET_RMT_DATA(test_request, 10);
442 rmp->remote_item.entries[0].entry = test_request;
443 rmp->tx_interrupt();
444 UT_ASSERT_INT(
445 (int)wait_for_completion_timeout(
446 &rmp->cb_completion, HZ / 2),
447 >, 0);
448
449 /* Verify CLEARALL response */
450 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
451 ret = msm_smp2p_out_read(local, &test_response);
452 UT_ASSERT_INT(ret, ==, 0);
453 test_response = SMP2P_GET_RMT_DATA(test_response);
454 UT_ASSERT_INT(test_response, ==, 0);
455
456 ret = msm_smp2p_deinit_rmt_lpb_proc(SMP2P_REMOTE_MOCK_PROC);
457 UT_ASSERT_INT(ret, ==, 0);
458 seq_printf(s, "\tOK\n");
459 } while (0);
460
461 if (failed) {
462 pr_err("%s: Failed\n", __func__);
463 seq_printf(s, "\tFailed\n");
464 msm_smp2p_deinit_rmt_lpb_proc(SMP2P_REMOTE_MOCK_PROC);
465 }
466}
467
468/**
469 * smp2p_ut_remote_inout_core - Verify inbound/outbound functionality.
470 *
471 * @s: pointer to output file
472 * @remote_pid: Remote processor to test
473 *
474 * This test verifies inbound/outbound functionality for the remote processor.
475 */
476static void smp2p_ut_remote_inout_core(struct seq_file *s, int remote_pid)
477{
478 int failed = 0;
479 struct msm_smp2p_out *handle;
480 int ret;
481 uint32_t test_request;
482 uint32_t test_response = 0;
483 static struct mock_cb_data cb_out;
484 static struct mock_cb_data cb_in;
485
486 seq_printf(s, "Running %s for '%s' remote pid %d\n",
487 __func__, smp2p_pid_to_name(remote_pid), remote_pid);
488 mock_cb_data_init(&cb_out);
489 mock_cb_data_init(&cb_in);
490 do {
491 /* Open output entry */
492 ret = msm_smp2p_out_open(remote_pid, "smp2p",
493 &cb_out.nb, &handle);
494 UT_ASSERT_INT(ret, ==, 0);
495 UT_ASSERT_INT(
496 (int)wait_for_completion_timeout(
497 &cb_out.cb_completion, HZ / 2),
498 >, 0);
499 UT_ASSERT_INT(cb_out.cb_count, ==, 1);
500 UT_ASSERT_INT(cb_out.event_open, ==, 1);
501
502 /* Open inbound entry */
503 ret = msm_smp2p_in_register(remote_pid, "smp2p",
504 &cb_in.nb);
505 UT_ASSERT_INT(ret, ==, 0);
506 UT_ASSERT_INT(
507 (int)wait_for_completion_timeout(
508 &cb_in.cb_completion, HZ / 2),
509 >, 0);
510 UT_ASSERT_INT(cb_in.cb_count, ==, 1);
511 UT_ASSERT_INT(cb_in.event_open, ==, 1);
512
513 /* Write an echo request */
514 mock_cb_data_reset(&cb_out);
515 mock_cb_data_reset(&cb_in);
516 test_request = 0x0;
517 SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
518 SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_ECHO);
519 SMP2P_SET_RMT_DATA(test_request, 0xAA55);
520 ret = msm_smp2p_out_write(handle, test_request);
521 UT_ASSERT_INT(ret, ==, 0);
522
523 /* Verify inbound reply */
524 UT_ASSERT_INT(
525 (int)wait_for_completion_timeout(
526 &cb_in.cb_completion, HZ / 2),
527 >, 0);
528 UT_ASSERT_INT(cb_in.cb_count, ==, 1);
529 UT_ASSERT_INT(cb_in.event_entry_update, ==, 1);
530 UT_ASSERT_INT(SMP2P_GET_RMT_DATA(
531 cb_in.entry_data.current_value), ==, 0xAA55);
532
533 ret = msm_smp2p_in_read(remote_pid, "smp2p", &test_response);
534 UT_ASSERT_INT(ret, ==, 0);
535 UT_ASSERT_INT(0, ==, SMP2P_GET_RMT_CMD_TYPE(test_response));
536 UT_ASSERT_INT(SMP2P_LB_CMD_ECHO, ==,
537 SMP2P_GET_RMT_CMD(test_response));
538 UT_ASSERT_INT(0xAA55, ==, SMP2P_GET_RMT_DATA(test_response));
539
540 /* Write a clear all request */
541 mock_cb_data_reset(&cb_in);
542 test_request = 0x0;
543 SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
544 SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_CLEARALL);
545 SMP2P_SET_RMT_DATA(test_request, 0xAA55);
546 ret = msm_smp2p_out_write(handle, test_request);
547 UT_ASSERT_INT(ret, ==, 0);
548
549 /* Verify inbound reply */
550 UT_ASSERT_INT(
551 (int)wait_for_completion_timeout(
552 &cb_in.cb_completion, HZ / 2),
553 >, 0);
554 UT_ASSERT_INT(cb_in.cb_count, ==, 1);
555 UT_ASSERT_INT(cb_in.event_entry_update, ==, 1);
556 UT_ASSERT_INT(SMP2P_GET_RMT_DATA(
557 cb_in.entry_data.current_value), ==, 0x0000);
558
559 ret = msm_smp2p_in_read(remote_pid, "smp2p", &test_response);
560 UT_ASSERT_INT(ret, ==, 0);
561 UT_ASSERT_INT(0, ==, SMP2P_GET_RMT_CMD_TYPE(test_response));
562 UT_ASSERT_INT(0x0000, ==, SMP2P_GET_RMT_DATA(test_response));
563
564 /* Write a decrement request */
565 mock_cb_data_reset(&cb_in);
566 test_request = 0x0;
567 SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
568 SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_PINGPONG);
569 SMP2P_SET_RMT_DATA(test_request, 0xAA55);
570 ret = msm_smp2p_out_write(handle, test_request);
571 UT_ASSERT_INT(ret, ==, 0);
572
573 /* Verify inbound reply */
574 UT_ASSERT_INT(
575 (int)wait_for_completion_timeout(
576 &cb_in.cb_completion, HZ / 2),
577 >, 0);
578 UT_ASSERT_INT(cb_in.cb_count, ==, 1);
579 UT_ASSERT_INT(cb_in.event_entry_update, ==, 1);
580 UT_ASSERT_INT(SMP2P_GET_RMT_DATA(
581 cb_in.entry_data.current_value), ==, 0xAA54);
582
583 ret = msm_smp2p_in_read(remote_pid, "smp2p", &test_response);
584 UT_ASSERT_INT(ret, ==, 0);
585 UT_ASSERT_INT(0, ==, SMP2P_GET_RMT_CMD_TYPE(test_response));
586 UT_ASSERT_INT(SMP2P_LB_CMD_PINGPONG, ==,
587 SMP2P_GET_RMT_CMD(test_response));
588 UT_ASSERT_INT(0xAA54, ==, SMP2P_GET_RMT_DATA(test_response));
589
590 /* Test the ignore flag */
591 mock_cb_data_reset(&cb_in);
592 test_request = 0x0;
593 SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
594 SMP2P_SET_RMT_CMD(test_request, SMP2P_RLPB_IGNORE);
595 SMP2P_SET_RMT_DATA(test_request, 0xAA55);
596 ret = msm_smp2p_out_write(handle, test_request);
597 UT_ASSERT_INT(ret, ==, 0);
598
599 UT_ASSERT_INT(
600 (int)wait_for_completion_timeout(
601 &cb_in.cb_completion, HZ / 2),
602 ==, 0);
603 UT_ASSERT_INT(cb_in.cb_count, ==, 0);
604 UT_ASSERT_INT(cb_in.event_entry_update, ==, 0);
605 ret = msm_smp2p_in_read(remote_pid, "smp2p", &test_response);
606 UT_ASSERT_INT(ret, ==, 0);
607 UT_ASSERT_INT(0xAA54, ==, SMP2P_GET_RMT_DATA(test_response));
608
609 /* Cleanup */
610 ret = msm_smp2p_out_close(&handle);
611 UT_ASSERT_INT(ret, ==, 0);
612 UT_ASSERT_PTR(handle, ==, 0);
613 ret = msm_smp2p_in_unregister(remote_pid, "smp2p", &cb_in.nb);
614 UT_ASSERT_INT(ret, ==, 0);
615
616 seq_printf(s, "\tOK\n");
617 } while (0);
618
619 if (failed) {
620 if (handle)
621 (void)msm_smp2p_out_close(&handle);
622 (void)msm_smp2p_in_unregister(remote_pid, "smp2p", &cb_in.nb);
623
624 pr_err("%s: Failed\n", __func__);
625 seq_printf(s, "\tFailed\n");
626 }
627}
628
629/**
630 * smp2p_ut_remote_inout - Verify inbound/outbound functionality for all.
631 *
632 * @s: pointer to output file
633 *
634 * This test verifies inbound and outbound functionality for all
635 * configured remote processor.
636 */
637static void smp2p_ut_remote_inout(struct seq_file *s)
638{
639 struct smp2p_interrupt_config *int_cfg;
640 int pid;
641
642 int_cfg = smp2p_get_interrupt_config();
643 if (!int_cfg) {
644 seq_printf(s,
645 "Remote processor config unavailable\n");
646 return;
647 }
648
649 for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid) {
650 if (!int_cfg[pid].is_configured)
651 continue;
652
653 msm_smp2p_deinit_rmt_lpb_proc(pid);
654 smp2p_ut_remote_inout_core(s, pid);
655 msm_smp2p_init_rmt_lpb_proc(pid);
656 }
657}
658
659/**
660 * smp2p_ut_remote_out_max_entries_core - Verify open functionality.
661 *
662 * @s: pointer to output file
663 * @remote_pid: Remote processor for which the test is executed.
664 *
665 * This test verifies open functionality by creating maximum outbound entries.
666 */
667static void smp2p_ut_remote_out_max_entries_core(struct seq_file *s,
668 int remote_pid)
669{
670 int j = 0;
671 int failed = 0;
672 struct msm_smp2p_out *handle[SMP2P_MAX_ENTRY];
673 int ret;
674 static struct mock_cb_data cb_out[SMP2P_MAX_ENTRY];
675 char entry_name[SMP2P_MAX_ENTRY_NAME];
676 int num_created;
677
678 seq_printf(s, "Running %s for '%s' remote pid %d\n",
679 __func__, smp2p_pid_to_name(remote_pid), remote_pid);
680
681 for (j = 0; j < SMP2P_MAX_ENTRY; j++) {
682 handle[j] = NULL;
683 mock_cb_data_init(&cb_out[j]);
684 }
685
686 do {
687 num_created = 0;
688 for (j = 0; j < SMP2P_MAX_ENTRY; j++) {
689 /* Open as many output entries as possible */
690 scnprintf((char *)entry_name, SMP2P_MAX_ENTRY_NAME,
691 "smp2p%d", j);
692 ret = msm_smp2p_out_open(remote_pid, entry_name,
693 &cb_out[j].nb, &handle[j]);
694 if (ret == -ENOMEM)
695 /* hit max number */
696 break;
697 UT_ASSERT_INT(ret, ==, 0);
698 ++num_created;
699 }
700 if (failed)
701 break;
702
703 /* verify we created more than 1 entry */
704 UT_ASSERT_INT(num_created, <=, SMP2P_MAX_ENTRY);
705 UT_ASSERT_INT(num_created, >, 0);
706
707 seq_printf(s, "\tOK\n");
708 } while (0);
709
710 if (failed) {
711 pr_err("%s: Failed\n", __func__);
712 seq_printf(s, "\tFailed\n");
713 }
714
715 /* cleanup */
716 for (j = 0; j < SMP2P_MAX_ENTRY; j++)
717 ret = msm_smp2p_out_close(&handle[j]);
718}
719
720/**
721 * smp2p_ut_remote_out_max_entries - Verify open for all configured processors.
722 *
723 * @s: pointer to output file
724 *
725 * This test verifies creating max number of entries for
726 * all configured remote processor.
727 */
728static void smp2p_ut_remote_out_max_entries(struct seq_file *s)
729{
730 struct smp2p_interrupt_config *int_cfg;
731 int pid;
732
733 int_cfg = smp2p_get_interrupt_config();
734 if (!int_cfg) {
735 seq_printf(s,
736 "Remote processor config unavailable\n");
737 return;
738 }
739
740 for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid) {
741 if (!int_cfg[pid].is_configured)
742 continue;
743
744 smp2p_ut_remote_out_max_entries_core(s, pid);
745 }
746}
747
748/**
749 * smp2p_ut_local_in_max_entries - Verify registering and unregistering.
750 *
751 * @s: pointer to output file
752 *
753 * This test verifies registering and unregistering for inbound entries using
754 * the remote mock processor.
755 */
756static void smp2p_ut_local_in_max_entries(struct seq_file *s)
757{
758 int j = 0;
759 int failed = 0;
760 struct msm_smp2p_remote_mock *rmp = NULL;
761 int ret;
762 static struct mock_cb_data cb_in[SMP2P_MAX_ENTRY];
763 static struct mock_cb_data cb_out;
764
765 seq_printf(s, "Running %s\n", __func__);
766
767 for (j = 0; j < SMP2P_MAX_ENTRY; j++)
768 mock_cb_data_init(&cb_in[j]);
769
770 mock_cb_data_init(&cb_out);
771
772 do {
773 /* Initialize mock edge */
774 ret = smp2p_reset_mock_edge();
775 UT_ASSERT_INT(ret, ==, 0);
776
777 rmp = msm_smp2p_get_remote_mock();
778 UT_ASSERT_PTR(rmp, !=, NULL);
779
780 rmp->rx_interrupt_count = 0;
781 memset(&rmp->remote_item, 0,
782 sizeof(struct smp2p_smem_item));
783 rmp->remote_item.header.magic = SMP2P_MAGIC;
784 SMP2P_SET_LOCAL_PID(
785 rmp->remote_item.header.rem_loc_proc_id,
786 SMP2P_REMOTE_MOCK_PROC);
787 SMP2P_SET_REMOTE_PID(
788 rmp->remote_item.header.rem_loc_proc_id,
789 SMP2P_APPS_PROC);
790 SMP2P_SET_VERSION(
791 rmp->remote_item.header.feature_version, 1);
792 SMP2P_SET_FEATURES(
793 rmp->remote_item.header.feature_version, 0);
794 SMP2P_SET_ENT_TOTAL(
795 rmp->remote_item.header.valid_total_ent, SMP2P_MAX_ENTRY);
796 SMP2P_SET_ENT_VALID(
797 rmp->remote_item.header.valid_total_ent, 0);
Eric Holmberg7aadc772013-09-16 16:52:51 -0600798 rmp->remote_item.header.flags = 0x0;
Eric Holmberg6275b602012-11-19 13:05:04 -0700799 msm_smp2p_set_remote_mock_exists(true);
800
801 /* Create Max Entries in the remote mock object */
802 for (j = 0; j < SMP2P_MAX_ENTRY; j++) {
803 scnprintf(rmp->remote_item.entries[j].name,
804 SMP2P_MAX_ENTRY_NAME, "smp2p%d", j);
805 rmp->remote_item.entries[j].entry = 0;
806 rmp->tx_interrupt();
807 }
808
809 /* Register for in entries */
810 for (j = 0; j < SMP2P_MAX_ENTRY; j++) {
811 ret = msm_smp2p_in_register(SMP2P_REMOTE_MOCK_PROC,
812 rmp->remote_item.entries[j].name,
813 &(cb_in[j].nb));
814 UT_ASSERT_INT(ret, ==, 0);
815 UT_ASSERT_INT(
816 (int)wait_for_completion_timeout(
817 &(cb_in[j].cb_completion), HZ / 2),
818 >, 0);
819 UT_ASSERT_INT(cb_in[j].cb_count, ==, 1);
820 UT_ASSERT_INT(cb_in[j].event_entry_update, ==, 0);
821 }
822 UT_ASSERT_INT(j, ==, SMP2P_MAX_ENTRY);
823
824 /* Unregister */
825 for (j = 0; j < SMP2P_MAX_ENTRY; j++) {
826 ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
827 rmp->remote_item.entries[j].name,
828 &(cb_in[j].nb));
829 UT_ASSERT_INT(ret, ==, 0);
830 }
831 UT_ASSERT_INT(j, ==, SMP2P_MAX_ENTRY);
832
833 seq_printf(s, "\tOK\n");
834 } while (0);
835
836 if (failed) {
837 pr_err("%s: Failed\n", __func__);
838 seq_printf(s, "\tFailed\n");
839
840 for (j = 0; j < SMP2P_MAX_ENTRY; j++)
841 ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
842 rmp->remote_item.entries[j].name,
843 &(cb_in[j].nb));
844 }
845}
846
Eric Holmberg4e9a83a2013-02-04 16:43:20 -0700847/**
848 * smp2p_ut_local_in_multiple - Verify Multiple Inbound Registration.
849 *
850 * @s: pointer to output file
851 *
852 * This test verifies multiple clients registering for same inbound entries
853 * using the remote mock processor.
854 */
855static void smp2p_ut_local_in_multiple(struct seq_file *s)
856{
857 int failed = 0;
858 struct msm_smp2p_remote_mock *rmp = NULL;
859 int ret;
860 static struct mock_cb_data cb_in_1;
861 static struct mock_cb_data cb_in_2;
862 static struct mock_cb_data cb_out;
863
864 seq_printf(s, "Running %s\n", __func__);
865
866 mock_cb_data_init(&cb_in_1);
867 mock_cb_data_init(&cb_in_2);
868 mock_cb_data_init(&cb_out);
869
870 do {
871 /* Initialize mock edge */
872 ret = smp2p_reset_mock_edge();
873 UT_ASSERT_INT(ret, ==, 0);
874
875 rmp = msm_smp2p_get_remote_mock();
876 UT_ASSERT_PTR(rmp, !=, NULL);
877
878 rmp->rx_interrupt_count = 0;
879 memset(&rmp->remote_item, 0,
880 sizeof(struct smp2p_smem_item));
881 rmp->remote_item.header.magic = SMP2P_MAGIC;
882 SMP2P_SET_LOCAL_PID(
883 rmp->remote_item.header.rem_loc_proc_id,
884 SMP2P_REMOTE_MOCK_PROC);
885 SMP2P_SET_REMOTE_PID(
886 rmp->remote_item.header.rem_loc_proc_id,
887 SMP2P_APPS_PROC);
888 SMP2P_SET_VERSION(
889 rmp->remote_item.header.feature_version, 1);
890 SMP2P_SET_FEATURES(
891 rmp->remote_item.header.feature_version, 0);
892 SMP2P_SET_ENT_TOTAL(
893 rmp->remote_item.header.valid_total_ent, 1);
894 SMP2P_SET_ENT_VALID(
895 rmp->remote_item.header.valid_total_ent, 0);
Eric Holmberg7aadc772013-09-16 16:52:51 -0600896 rmp->remote_item.header.flags = 0x0;
Eric Holmberg4e9a83a2013-02-04 16:43:20 -0700897 msm_smp2p_set_remote_mock_exists(true);
898
899 /* Create an Entry in the remote mock object */
900 scnprintf(rmp->remote_item.entries[0].name,
901 SMP2P_MAX_ENTRY_NAME, "smp2p%d", 1);
902 rmp->remote_item.entries[0].entry = 0;
903 rmp->tx_interrupt();
904
905 /* Register multiple clients for the inbound entry */
906 ret = msm_smp2p_in_register(SMP2P_REMOTE_MOCK_PROC,
907 rmp->remote_item.entries[0].name,
908 &cb_in_1.nb);
909 UT_ASSERT_INT(ret, ==, 0);
910 UT_ASSERT_INT(
911 (int)wait_for_completion_timeout(
912 &(cb_in_1.cb_completion), HZ / 2),
913 >, 0);
914 UT_ASSERT_INT(cb_in_1.cb_count, ==, 1);
915 UT_ASSERT_INT(cb_in_1.event_entry_update, ==, 0);
916
917 ret = msm_smp2p_in_register(SMP2P_REMOTE_MOCK_PROC,
918 rmp->remote_item.entries[0].name,
919 &cb_in_2.nb);
920 UT_ASSERT_INT(ret, ==, 0);
921 UT_ASSERT_INT(
922 (int)wait_for_completion_timeout(
923 &(cb_in_2.cb_completion), HZ / 2),
924 >, 0);
925 UT_ASSERT_INT(cb_in_2.cb_count, ==, 1);
926 UT_ASSERT_INT(cb_in_2.event_entry_update, ==, 0);
927
928
929 /* Unregister the clients */
930 ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
931 rmp->remote_item.entries[0].name,
932 &(cb_in_1.nb));
933 UT_ASSERT_INT(ret, ==, 0);
934
935 ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
936 rmp->remote_item.entries[0].name,
937 &(cb_in_2.nb));
938 UT_ASSERT_INT(ret, ==, 0);
939
940 seq_printf(s, "\tOK\n");
941 } while (0);
942
943 if (failed) {
944 pr_err("%s: Failed\n", __func__);
945 seq_printf(s, "\tFailed\n");
946
947 ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
948 rmp->remote_item.entries[0].name,
949 &(cb_in_1.nb));
950
951 ret = msm_smp2p_in_unregister(SMP2P_REMOTE_MOCK_PROC,
952 rmp->remote_item.entries[0].name,
953 &(cb_in_2.nb));
954 }
955}
956
Eric Holmberg7aadc772013-09-16 16:52:51 -0600957/**
958 * smp2p_ut_local_ssr_ack - Verify SSR Done/ACK Feature
959 *
960 * @s: pointer to output file
961 */
962static void smp2p_ut_local_ssr_ack(struct seq_file *s)
963{
964 int failed = 0;
965 struct msm_smp2p_remote_mock *rmp = NULL;
966 int ret;
967
968 seq_printf(s, "Running %s\n", __func__);
969 do {
970 struct smp2p_smem *rhdr;
971 struct smp2p_smem *lhdr;
972 int negotiation_state;
973
974 /* initialize v1 without SMP2P_FEATURE_SSR_ACK enabled */
975 ret = smp2p_reset_mock_edge();
976 UT_ASSERT_INT(ret, ==, 0);
977 rmp = msm_smp2p_get_remote_mock();
978 UT_ASSERT_PTR(rmp, !=, NULL);
979 rhdr = &rmp->remote_item.header;
980
981 rmp->rx_interrupt_count = 0;
982 memset(&rmp->remote_item, 0, sizeof(struct smp2p_smem_item));
983 rhdr->magic = SMP2P_MAGIC;
984 SMP2P_SET_LOCAL_PID(rhdr->rem_loc_proc_id,
985 SMP2P_REMOTE_MOCK_PROC);
986 SMP2P_SET_REMOTE_PID(rhdr->rem_loc_proc_id, SMP2P_APPS_PROC);
987 SMP2P_SET_VERSION(rhdr->feature_version, 1);
988 SMP2P_SET_FEATURES(rhdr->feature_version, 0);
989 SMP2P_SET_ENT_TOTAL(rhdr->valid_total_ent, SMP2P_MAX_ENTRY);
990 SMP2P_SET_ENT_VALID(rhdr->valid_total_ent, 0);
991 rhdr->flags = 0x0;
992 msm_smp2p_set_remote_mock_exists(true);
993 rmp->tx_interrupt();
994
995 /* verify edge is open */
996 lhdr = smp2p_get_out_item(SMP2P_REMOTE_MOCK_PROC,
997 &negotiation_state);
998 UT_ASSERT_PTR(NULL, !=, lhdr);
999 UT_ASSERT_INT(negotiation_state, ==, SMP2P_EDGE_STATE_OPENED);
1000 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
1001
1002 /* verify no response to ack feature */
1003 rmp->rx_interrupt_count = 0;
1004 SMP2P_SET_RESTART_DONE(rhdr->flags, 1);
1005 rmp->tx_interrupt();
1006 UT_ASSERT_INT(0, ==, SMP2P_GET_RESTART_DONE(lhdr->flags));
1007 UT_ASSERT_INT(0, ==, SMP2P_GET_RESTART_ACK(lhdr->flags));
1008 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 0);
1009
1010 /* initialize v1 with SMP2P_FEATURE_SSR_ACK enabled */
1011 ret = smp2p_reset_mock_edge();
1012 UT_ASSERT_INT(ret, ==, 0);
1013 rmp = msm_smp2p_get_remote_mock();
1014 UT_ASSERT_PTR(rmp, !=, NULL);
1015 rhdr = &rmp->remote_item.header;
1016
1017 rmp->rx_interrupt_count = 0;
1018 memset(&rmp->remote_item, 0, sizeof(struct smp2p_smem_item));
1019 rhdr->magic = SMP2P_MAGIC;
1020 SMP2P_SET_LOCAL_PID(rhdr->rem_loc_proc_id,
1021 SMP2P_REMOTE_MOCK_PROC);
1022 SMP2P_SET_REMOTE_PID(rhdr->rem_loc_proc_id, SMP2P_APPS_PROC);
1023 SMP2P_SET_VERSION(rhdr->feature_version, 1);
1024 SMP2P_SET_FEATURES(rhdr->feature_version,
1025 SMP2P_FEATURE_SSR_ACK);
1026 SMP2P_SET_ENT_TOTAL(rhdr->valid_total_ent, SMP2P_MAX_ENTRY);
1027 SMP2P_SET_ENT_VALID(rhdr->valid_total_ent, 0);
1028 rmp->rx_interrupt_count = 0;
1029 rhdr->flags = 0x0;
1030 msm_smp2p_set_remote_mock_exists(true);
1031 rmp->tx_interrupt();
1032
1033 /* verify edge is open */
1034 lhdr = smp2p_get_out_item(SMP2P_REMOTE_MOCK_PROC,
1035 &negotiation_state);
1036 UT_ASSERT_PTR(NULL, !=, lhdr);
1037 UT_ASSERT_INT(negotiation_state, ==, SMP2P_EDGE_STATE_OPENED);
1038 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
1039
1040 /* verify response to ack feature */
1041 rmp->rx_interrupt_count = 0;
1042 SMP2P_SET_RESTART_DONE(rhdr->flags, 1);
1043 rmp->tx_interrupt();
1044 UT_ASSERT_INT(0, ==, SMP2P_GET_RESTART_DONE(lhdr->flags));
1045 UT_ASSERT_INT(1, ==, SMP2P_GET_RESTART_ACK(lhdr->flags));
1046 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
1047
1048 rmp->rx_interrupt_count = 0;
1049 SMP2P_SET_RESTART_DONE(rhdr->flags, 0);
1050 rmp->tx_interrupt();
1051 UT_ASSERT_INT(0, ==, SMP2P_GET_RESTART_DONE(lhdr->flags));
1052 UT_ASSERT_INT(0, ==, SMP2P_GET_RESTART_ACK(lhdr->flags));
1053 UT_ASSERT_INT(rmp->rx_interrupt_count, ==, 1);
1054
1055 seq_puts(s, "\tOK\n");
1056 } while (0);
1057
1058 if (failed) {
1059 pr_err("%s: Failed\n", __func__);
1060 seq_puts(s, "\tFailed\n");
1061 }
1062}
1063
1064/**
1065 * smp2p_ut_local_ssr_ack - Verify SSR Done/ACK Feature
1066 *
1067 * @s: pointer to output file
1068 * @rpid: Remote processor ID
1069 * @int_cfg: Interrupt config
1070 */
1071static void smp2p_ut_remotesubsys_ssr_ack(struct seq_file *s, uint32_t rpid,
1072 struct smp2p_interrupt_config *int_cfg)
1073{
1074 int failed = 0;
1075
1076 seq_printf(s, "Running %s\n", __func__);
1077 do {
1078 struct smp2p_smem *rhdr;
1079 struct smp2p_smem *lhdr;
1080 int negotiation_state;
1081 bool ssr_ack_enabled;
1082 uint32_t ssr_done_start;
1083
1084 lhdr = smp2p_get_out_item(rpid, &negotiation_state);
1085 UT_ASSERT_PTR(NULL, !=, lhdr);
1086 UT_ASSERT_INT(SMP2P_EDGE_STATE_OPENED, ==, negotiation_state);
1087
1088 rhdr = smp2p_get_in_item(rpid);
1089 UT_ASSERT_PTR(NULL, !=, rhdr);
1090
1091 /* get initial state of SSR flags */
1092 if (SMP2P_GET_FEATURES(rhdr->feature_version)
1093 & SMP2P_FEATURE_SSR_ACK)
1094 ssr_ack_enabled = true;
1095 else
1096 ssr_ack_enabled = false;
1097
1098 ssr_done_start = SMP2P_GET_RESTART_DONE(rhdr->flags);
1099 UT_ASSERT_INT(ssr_done_start, ==,
1100 SMP2P_GET_RESTART_ACK(lhdr->flags));
1101
1102 /* trigger restart */
1103 seq_printf(s, "Restarting '%s'\n", int_cfg->name);
1104 subsystem_restart(int_cfg->name);
1105 msleep(10*1000);
1106
1107 /* verify ack signaling */
1108 if (ssr_ack_enabled) {
1109 ssr_done_start ^= 1;
1110 UT_ASSERT_INT(ssr_done_start, ==,
1111 SMP2P_GET_RESTART_ACK(lhdr->flags));
1112 UT_ASSERT_INT(ssr_done_start, ==,
1113 SMP2P_GET_RESTART_DONE(rhdr->flags));
1114 UT_ASSERT_INT(0, ==,
1115 SMP2P_GET_RESTART_DONE(lhdr->flags));
1116 seq_puts(s, "\tSSR ACK Enabled and Toggled\n");
1117 } else {
1118 UT_ASSERT_INT(0, ==,
1119 SMP2P_GET_RESTART_DONE(lhdr->flags));
1120 UT_ASSERT_INT(0, ==,
1121 SMP2P_GET_RESTART_ACK(lhdr->flags));
1122
1123 UT_ASSERT_INT(0, ==,
1124 SMP2P_GET_RESTART_DONE(rhdr->flags));
1125 UT_ASSERT_INT(0, ==,
1126 SMP2P_GET_RESTART_ACK(rhdr->flags));
1127 seq_puts(s, "\tSSR ACK Disabled\n");
1128 }
1129
1130 seq_puts(s, "\tOK\n");
1131 } while (0);
1132
1133 if (failed) {
1134 pr_err("%s: Failed\n", __func__);
1135 seq_puts(s, "\tFailed\n");
1136 }
1137}
1138
1139/**
1140 * smp2p_ut_remote_ssr_ack - Verify SSR Done/ACK Feature
1141 *
1142 * @s: pointer to output file
1143 *
1144 * Triggers SSR for each subsystem.
1145 */
1146static void smp2p_ut_remote_ssr_ack(struct seq_file *s)
1147{
1148 struct smp2p_interrupt_config *int_cfg;
1149 int pid;
1150
1151 int_cfg = smp2p_get_interrupt_config();
1152 if (!int_cfg) {
1153 seq_puts(s,
1154 "Remote processor config unavailable\n");
1155 return;
1156 }
1157
1158 for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid) {
1159 if (!int_cfg[pid].is_configured)
1160 continue;
1161
1162 msm_smp2p_deinit_rmt_lpb_proc(pid);
1163 smp2p_ut_remotesubsys_ssr_ack(s, pid, &int_cfg[pid]);
1164 msm_smp2p_init_rmt_lpb_proc(pid);
1165 }
1166}
1167
Eric Holmberg6275b602012-11-19 13:05:04 -07001168static struct dentry *dent;
1169
1170static int debugfs_show(struct seq_file *s, void *data)
1171{
1172 void (*show)(struct seq_file *) = s->private;
1173
1174 show(s);
1175
1176 return 0;
1177}
1178
1179static int debug_open(struct inode *inode, struct file *file)
1180{
1181 return single_open(file, debugfs_show, inode->i_private);
1182}
1183
1184static const struct file_operations debug_ops = {
1185 .open = debug_open,
1186 .release = single_release,
1187 .read = seq_read,
1188 .llseek = seq_lseek,
1189};
1190
1191void smp2p_debug_create(const char *name,
1192 void (*show)(struct seq_file *))
1193{
1194 struct dentry *file;
1195
1196 file = debugfs_create_file(name, 0444, dent, show, &debug_ops);
1197 if (!file)
1198 pr_err("%s: unable to create file '%s'\n", __func__, name);
1199}
1200
1201static int __init smp2p_debugfs_init(void)
1202{
1203 dent = debugfs_create_dir("smp2p_test", 0);
1204 if (IS_ERR(dent))
1205 return PTR_ERR(dent);
1206
1207 /*
1208 * Add Unit Test entries.
1209 *
1210 * The idea with unit tests is that you can run all of them
1211 * from ADB shell by doing:
1212 * adb shell
1213 * cat ut*
1214 *
1215 * And if particular tests fail, you can then repeatedly run the
1216 * failing tests as you debug and resolve the failing test.
1217 */
1218 smp2p_debug_create("ut_local_basic",
1219 smp2p_ut_local_basic);
1220 smp2p_debug_create("ut_local_late_open",
1221 smp2p_ut_local_late_open);
1222 smp2p_debug_create("ut_local_early_open",
1223 smp2p_ut_local_early_open);
1224 smp2p_debug_create("ut_mock_loopback",
1225 smp2p_ut_mock_loopback);
1226 smp2p_debug_create("ut_remote_inout",
1227 smp2p_ut_remote_inout);
1228 smp2p_debug_create("ut_local_in_max_entries",
1229 smp2p_ut_local_in_max_entries);
1230 smp2p_debug_create("ut_remote_out_max_entries",
1231 smp2p_ut_remote_out_max_entries);
Eric Holmberg4e9a83a2013-02-04 16:43:20 -07001232 smp2p_debug_create("ut_local_in_multiple",
1233 smp2p_ut_local_in_multiple);
Eric Holmberg7aadc772013-09-16 16:52:51 -06001234 smp2p_debug_create("ut_local_ssr_ack",
1235 smp2p_ut_local_ssr_ack);
1236 smp2p_debug_create("ut_remote_ssr_ack",
1237 smp2p_ut_remote_ssr_ack);
Eric Holmberg6275b602012-11-19 13:05:04 -07001238
1239 return 0;
1240}
1241module_init(smp2p_debugfs_init);