blob: 855482bf9a939550ea673bd63c38b73e1033ca70 [file] [log] [blame]
Brian Swetland03e00cd2009-07-01 17:58:37 -07001/* arch/arm/mach-msm/smd_debug.c
2 *
3 * Copyright (C) 2007 Google, Inc.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004 * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
Brian Swetland03e00cd2009-07-01 17:58:37 -07005 * Author: Brian Swetland <swetland@google.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/debugfs.h>
19#include <linux/list.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070020#include <linux/ctype.h>
Brian Swetland03e00cd2009-07-01 17:58:37 -070021
22#include <mach/msm_iomap.h>
23
24#include "smd_private.h"
25
26#if defined(CONFIG_DEBUG_FS)
27
28static char *chstate(unsigned n)
29{
30 switch (n) {
31 case SMD_SS_CLOSED:
32 return "CLOSED";
33 case SMD_SS_OPENING:
34 return "OPENING";
35 case SMD_SS_OPENED:
36 return "OPENED";
37 case SMD_SS_FLUSHING:
38 return "FLUSHING";
39 case SMD_SS_CLOSING:
40 return "CLOSING";
41 case SMD_SS_RESET:
42 return "RESET";
43 case SMD_SS_RESET_OPENING:
44 return "ROPENING";
45 default:
46 return "UNKNOWN";
47 }
48}
49
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070050static int debug_f3(char *buf, int max)
Brian Swetland03e00cd2009-07-01 17:58:37 -070051{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070052 char *x;
53 int size;
54 int i = 0, j = 0;
55 unsigned cols = 0;
56 char str[4*sizeof(unsigned)+1] = {0};
Brian Swetland03e00cd2009-07-01 17:58:37 -070057
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070058 i += scnprintf(buf + i, max - i,
59 "Printing to log\n");
60
61 x = smem_get_entry(SMEM_ERR_F3_TRACE_LOG, &size);
62 if (x != 0) {
63 pr_info("smem: F3 TRACE LOG\n");
64 while (size > 0) {
65 if (size >= sizeof(unsigned)) {
66 pr_info("%08x", *((unsigned *) x));
67 for (j = 0; j < sizeof(unsigned); ++j)
68 if (isprint(*(x+j)))
69 str[cols*sizeof(unsigned) + j]
70 = *(x+j);
71 else
72 str[cols*sizeof(unsigned) + j]
73 = '-';
74 x += sizeof(unsigned);
75 size -= sizeof(unsigned);
76 } else {
77 while (size-- > 0)
78 pr_info("%02x", (unsigned) *x++);
79 break;
80 }
81 if (cols == 3) {
82 cols = 0;
83 str[4*sizeof(unsigned)] = 0;
84 pr_info(" %s\n", str);
85 str[0] = 0;
86 } else {
87 cols++;
88 pr_info(" ");
89 }
90 }
91 pr_info("\n");
92 }
93
94 return max;
95}
96
97static int debug_diag(char *buf, int max)
98{
99 int i = 0;
100
101 i += scnprintf(buf + i, max - i,
102 "Printing to log\n");
103 smd_diag();
104
105 return i;
106}
107
108static int debug_modem_err_f3(char *buf, int max)
109{
110 char *x;
111 int size;
112 int i = 0, j = 0;
113 unsigned cols = 0;
114 char str[4*sizeof(unsigned)+1] = {0};
115
116 x = smem_get_entry(SMEM_ERR_F3_TRACE_LOG, &size);
117 if (x != 0) {
118 pr_info("smem: F3 TRACE LOG\n");
119 while (size > 0 && max - i) {
120 if (size >= sizeof(unsigned)) {
121 i += scnprintf(buf + i, max - i, "%08x",
122 *((unsigned *) x));
123 for (j = 0; j < sizeof(unsigned); ++j)
124 if (isprint(*(x+j)))
125 str[cols*sizeof(unsigned) + j]
126 = *(x+j);
127 else
128 str[cols*sizeof(unsigned) + j]
129 = '-';
130 x += sizeof(unsigned);
131 size -= sizeof(unsigned);
132 } else {
133 while (size-- > 0 && max - i)
134 i += scnprintf(buf + i, max - i,
135 "%02x",
136 (unsigned) *x++);
137 break;
138 }
139 if (cols == 3) {
140 cols = 0;
141 str[4*sizeof(unsigned)] = 0;
142 i += scnprintf(buf + i, max - i, " %s\n",
143 str);
144 str[0] = 0;
145 } else {
146 cols++;
147 i += scnprintf(buf + i, max - i, " ");
148 }
149 }
150 i += scnprintf(buf + i, max - i, "\n");
151 }
152
153 return i;
154}
155
156static int debug_modem_err(char *buf, int max)
157{
158 char *x;
159 int size;
160 int i = 0;
161
162 x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
163 if (x != 0) {
164 x[SZ_DIAG_ERR_MSG - 1] = 0;
165 i += scnprintf(buf + i, max - i,
166 "smem: DIAG '%s'\n", x);
167 }
168
169 x = smem_get_entry(SMEM_ERR_CRASH_LOG, &size);
170 if (x != 0) {
171 x[size - 1] = 0;
172 i += scnprintf(buf + i, max - i,
173 "smem: CRASH LOG\n'%s'\n", x);
174 }
175 i += scnprintf(buf + i, max - i, "\n");
176
177 return i;
178}
179
180static int debug_read_diag_msg(char *buf, int max)
181{
182 char *msg;
183 int i = 0;
184
185 msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
186
187 if (msg) {
188 msg[SZ_DIAG_ERR_MSG - 1] = 0;
189 i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg);
190 }
191 return i;
192}
193
194static int dump_ch(char *buf, int max, int n,
195 struct smd_half_channel *s,
196 struct smd_half_channel *r,
197 unsigned size)
198{
Brian Swetland03e00cd2009-07-01 17:58:37 -0700199 return scnprintf(
200 buf, max,
201 "ch%02d:"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700202 " %8s(%04d/%04d) %c%c%c%c%c%c%c%c <->"
203 " %8s(%04d/%04d) %c%c%c%c%c%c%c%c : %5x\n", n,
Brian Swetland03e00cd2009-07-01 17:58:37 -0700204 chstate(s->state), s->tail, s->head,
205 s->fDSR ? 'D' : 'd',
206 s->fCTS ? 'C' : 'c',
207 s->fCD ? 'C' : 'c',
208 s->fRI ? 'I' : 'i',
209 s->fHEAD ? 'W' : 'w',
210 s->fTAIL ? 'R' : 'r',
211 s->fSTATE ? 'S' : 's',
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700212 s->fBLOCKREADINTR ? 'B' : 'b',
Brian Swetland03e00cd2009-07-01 17:58:37 -0700213 chstate(r->state), r->tail, r->head,
214 r->fDSR ? 'D' : 'd',
215 r->fCTS ? 'R' : 'r',
216 r->fCD ? 'C' : 'c',
217 r->fRI ? 'I' : 'i',
218 r->fHEAD ? 'W' : 'w',
219 r->fTAIL ? 'R' : 'r',
Brian Swetland37521a32009-07-01 18:30:47 -0700220 r->fSTATE ? 'S' : 's',
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700221 r->fBLOCKREADINTR ? 'B' : 'b',
222 size
Brian Swetland03e00cd2009-07-01 17:58:37 -0700223 );
224}
225
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700226static int debug_read_smsm_state(char *buf, int max)
Brian Swetland03e00cd2009-07-01 17:58:37 -0700227{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700228 uint32_t *smsm;
229 int n, i = 0;
230
231 smsm = smem_find(ID_SHARED_STATE,
232 SMSM_NUM_ENTRIES * sizeof(uint32_t));
233
234 if (smsm)
235 for (n = 0; n < SMSM_NUM_ENTRIES; n++)
236 i += scnprintf(buf + i, max - i, "entry %d: 0x%08x\n",
237 n, smsm[n]);
238
239 return i;
240}
241
242struct SMSM_CB_DATA {
243 int cb_count;
244 void *data;
245 uint32_t old_state;
246 uint32_t new_state;
247};
248static struct SMSM_CB_DATA smsm_cb_data;
249
250static void smsm_state_cb(void *data, uint32_t old_state, uint32_t new_state)
251{
252 smsm_cb_data.cb_count++;
253 smsm_cb_data.old_state = old_state;
254 smsm_cb_data.new_state = new_state;
255 smsm_cb_data.data = data;
256}
257
258#define UT_EQ_INT(a, b) \
259 if ((a) != (b)) { \
260 i += scnprintf(buf + i, max - i, \
261 "%s:%d " #a "(%d) != " #b "(%d)\n", \
262 __func__, __LINE__, \
263 a, b); \
264 break; \
265 } \
266 do {} while (0)
267
268#define SMSM_CB_TEST_INIT() \
269 do { \
270 smsm_cb_data.cb_count = 0; \
271 smsm_cb_data.old_state = 0; \
272 smsm_cb_data.new_state = 0; \
273 smsm_cb_data.data = 0; \
274 } while (0)
275
276
277static int debug_test_smsm(char *buf, int max)
278{
Brian Swetland03e00cd2009-07-01 17:58:37 -0700279 int i = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700280 int test_num = 0;
281 int ret;
Brian Swetland03e00cd2009-07-01 17:58:37 -0700282
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700283 /* Test case 1 - Register new callback for notification */
284 do {
285 test_num++;
286 SMSM_CB_TEST_INIT();
287 ret = smsm_state_cb_register(SMSM_APPS_STATE, SMSM_SMDINIT,
288 smsm_state_cb, (void *)0x1234);
289 UT_EQ_INT(ret, 0);
Brian Swetland03e00cd2009-07-01 17:58:37 -0700290
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700291 /* de-assert SMSM_SMD_INIT to trigger state update */
292 UT_EQ_INT(smsm_cb_data.cb_count, 0);
293 smsm_change_state(SMSM_APPS_STATE, SMSM_SMDINIT, 0x0);
Brian Swetland03e00cd2009-07-01 17:58:37 -0700294
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700295 UT_EQ_INT(smsm_cb_data.cb_count, 1);
296 UT_EQ_INT(smsm_cb_data.cb_count, 1);
297 UT_EQ_INT(smsm_cb_data.old_state & SMSM_SMDINIT, SMSM_SMDINIT);
298 UT_EQ_INT(smsm_cb_data.new_state & SMSM_SMDINIT, 0x0);
299 UT_EQ_INT((int)smsm_cb_data.data, 0x1234);
300
301 /* re-assert SMSM_SMD_INIT to trigger state update */
302 smsm_change_state(SMSM_APPS_STATE, 0x0, SMSM_SMDINIT);
303 UT_EQ_INT(smsm_cb_data.cb_count, 2);
304 UT_EQ_INT(smsm_cb_data.old_state & SMSM_SMDINIT, 0x0);
305 UT_EQ_INT(smsm_cb_data.new_state & SMSM_SMDINIT, SMSM_SMDINIT);
306
307 /* deregister callback */
308 ret = smsm_state_cb_deregister(SMSM_APPS_STATE, SMSM_SMDINIT,
309 smsm_state_cb, (void *)0x1234);
310 UT_EQ_INT(ret, 2);
311
312 /* make sure state change doesn't cause any more callbacks */
313 smsm_change_state(SMSM_APPS_STATE, SMSM_SMDINIT, 0x0);
314 smsm_change_state(SMSM_APPS_STATE, 0x0, SMSM_SMDINIT);
315 UT_EQ_INT(smsm_cb_data.cb_count, 2);
316
317 i += scnprintf(buf + i, max - i, "Test %d - PASS\n", test_num);
318 } while (0);
319
320 /* Test case 2 - Update already registered callback */
321 do {
322 test_num++;
323 SMSM_CB_TEST_INIT();
324 ret = smsm_state_cb_register(SMSM_APPS_STATE, SMSM_SMDINIT,
325 smsm_state_cb, (void *)0x1234);
326 UT_EQ_INT(ret, 0);
327 ret = smsm_state_cb_register(SMSM_APPS_STATE, SMSM_INIT,
328 smsm_state_cb, (void *)0x1234);
329 UT_EQ_INT(ret, 1);
330
331 /* verify both callback bits work */
332 UT_EQ_INT(smsm_cb_data.cb_count, 0);
333 smsm_change_state(SMSM_APPS_STATE, SMSM_SMDINIT, 0x0);
334 UT_EQ_INT(smsm_cb_data.cb_count, 1);
335 smsm_change_state(SMSM_APPS_STATE, 0x0, SMSM_SMDINIT);
336 UT_EQ_INT(smsm_cb_data.cb_count, 2);
337
338 smsm_change_state(SMSM_APPS_STATE, SMSM_INIT, 0x0);
339 UT_EQ_INT(smsm_cb_data.cb_count, 3);
340 smsm_change_state(SMSM_APPS_STATE, 0x0, SMSM_INIT);
341 UT_EQ_INT(smsm_cb_data.cb_count, 4);
342
343 /* deregister 1st callback */
344 ret = smsm_state_cb_deregister(SMSM_APPS_STATE, SMSM_SMDINIT,
345 smsm_state_cb, (void *)0x1234);
346 UT_EQ_INT(ret, 1);
347 smsm_change_state(SMSM_APPS_STATE, SMSM_SMDINIT, 0x0);
348 smsm_change_state(SMSM_APPS_STATE, 0x0, SMSM_SMDINIT);
349 UT_EQ_INT(smsm_cb_data.cb_count, 4);
350
351 smsm_change_state(SMSM_APPS_STATE, SMSM_INIT, 0x0);
352 UT_EQ_INT(smsm_cb_data.cb_count, 5);
353 smsm_change_state(SMSM_APPS_STATE, 0x0, SMSM_INIT);
354 UT_EQ_INT(smsm_cb_data.cb_count, 6);
355
356 /* deregister 2nd callback */
357 ret = smsm_state_cb_deregister(SMSM_APPS_STATE, SMSM_INIT,
358 smsm_state_cb, (void *)0x1234);
359 UT_EQ_INT(ret, 2);
360
361 /* make sure state change doesn't cause any more callbacks */
362 smsm_change_state(SMSM_APPS_STATE, SMSM_INIT, 0x0);
363 smsm_change_state(SMSM_APPS_STATE, 0x0, SMSM_INIT);
364 UT_EQ_INT(smsm_cb_data.cb_count, 6);
365
366 i += scnprintf(buf + i, max - i, "Test %d - PASS\n", test_num);
367 } while (0);
368
369 /* Test case 3 - Two callback registrations with different data */
370 do {
371 test_num++;
372 SMSM_CB_TEST_INIT();
373 ret = smsm_state_cb_register(SMSM_APPS_STATE, SMSM_SMDINIT,
374 smsm_state_cb, (void *)0x1234);
375 UT_EQ_INT(ret, 0);
376 ret = smsm_state_cb_register(SMSM_APPS_STATE, SMSM_INIT,
377 smsm_state_cb, (void *)0x3456);
378 UT_EQ_INT(ret, 0);
379
380 /* verify both callbacks work */
381 UT_EQ_INT(smsm_cb_data.cb_count, 0);
382 smsm_change_state(SMSM_APPS_STATE, SMSM_SMDINIT, 0x0);
383 UT_EQ_INT(smsm_cb_data.cb_count, 1);
384 UT_EQ_INT((int)smsm_cb_data.data, 0x1234);
385
386 smsm_change_state(SMSM_APPS_STATE, SMSM_INIT, 0x0);
387 UT_EQ_INT(smsm_cb_data.cb_count, 2);
388 UT_EQ_INT((int)smsm_cb_data.data, 0x3456);
389
390 /* cleanup and unregister
391 * degregister in reverse to verify data field is
392 * being used
393 */
394 smsm_change_state(SMSM_APPS_STATE, 0x0, SMSM_SMDINIT);
395 smsm_change_state(SMSM_APPS_STATE, 0x0, SMSM_INIT);
396 ret = smsm_state_cb_deregister(SMSM_APPS_STATE,
397 SMSM_INIT,
398 smsm_state_cb, (void *)0x3456);
399 UT_EQ_INT(ret, 2);
400 ret = smsm_state_cb_deregister(SMSM_APPS_STATE,
401 SMSM_SMDINIT,
402 smsm_state_cb, (void *)0x1234);
403 UT_EQ_INT(ret, 2);
404
405 i += scnprintf(buf + i, max - i, "Test %d - PASS\n", test_num);
406 } while (0);
407
Brian Swetland03e00cd2009-07-01 17:58:37 -0700408 return i;
409}
410
411static int debug_read_mem(char *buf, int max)
412{
413 unsigned n;
414 struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
415 struct smem_heap_entry *toc = shared->heap_toc;
416 int i = 0;
417
418 i += scnprintf(buf + i, max - i,
419 "heap: init=%d free=%d remain=%d\n",
420 shared->heap_info.initialized,
421 shared->heap_info.free_offset,
422 shared->heap_info.heap_remaining);
423
424 for (n = 0; n < SMEM_NUM_ITEMS; n++) {
425 if (toc[n].allocated == 0)
426 continue;
427 i += scnprintf(buf + i, max - i,
428 "%04d: offset %08x size %08x\n",
429 n, toc[n].offset, toc[n].size);
430 }
431 return i;
432}
433
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700434static int debug_read_ch_v1(char *buf, int max)
Brian Swetland03e00cd2009-07-01 17:58:37 -0700435{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700436 void *shared;
437 int n, i = 0;
Brian Swetland03e00cd2009-07-01 17:58:37 -0700438
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700439 for (n = 0; n < SMD_CHANNELS; n++) {
440 shared = smem_find(ID_SMD_CHANNELS + n,
441 2 * (sizeof(struct smd_half_channel) +
442 SMD_BUF_SIZE));
443
444 if (shared == 0)
445 continue;
446 i += dump_ch(buf + i, max - i, n, shared,
447 (shared + sizeof(struct smd_half_channel) +
448 SMD_BUF_SIZE), SMD_BUF_SIZE);
449 }
Brian Swetland03e00cd2009-07-01 17:58:37 -0700450
451 return i;
452}
453
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700454static int debug_read_ch_v2(char *buf, int max)
455{
456 void *shared, *buffer;
457 unsigned buffer_sz;
458 int n, i = 0;
459
460 for (n = 0; n < SMD_CHANNELS; n++) {
461 shared = smem_find(ID_SMD_CHANNELS + n,
462 2 * sizeof(struct smd_half_channel));
463
464 if (shared == 0)
465 continue;
466
467 buffer = smem_get_entry(SMEM_SMD_FIFO_BASE_ID + n, &buffer_sz);
468
469 if (buffer == 0)
470 continue;
471
472 i += dump_ch(buf + i, max - i, n, shared,
473 (shared + sizeof(struct smd_half_channel)),
474 buffer_sz / 2);
475 }
476
477 return i;
478}
479
480static int debug_read_ch(char *buf, int max)
481{
482 uint32_t *smd_ver;
483
484 smd_ver = smem_alloc(SMEM_VERSION_SMD, 32 * sizeof(uint32_t));
485
486 if (smd_ver && (((smd_ver[VERSION_MODEM] >> 16) >= 1) ||
487 ((smd_ver[VERSION_QDSP6] >> 16) >= 1) ||
488 ((smd_ver[VERSION_DSPS] >> 16) >= 1)))
489 return debug_read_ch_v2(buf, max);
490 else
491 return debug_read_ch_v1(buf, max);
492}
493
494static int debug_read_smem_version(char *buf, int max)
Brian Swetland03e00cd2009-07-01 17:58:37 -0700495{
496 struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700497 uint32_t n, version, i = 0;
498
499 for (n = 0; n < 32; n++) {
500 version = shared->version[n];
501 i += scnprintf(buf + i, max - i,
502 "entry %d: smem = %d proc_comm = %d\n", n,
503 version >> 16,
504 version & 0xffff);
505 }
506
507 return i;
508}
509
510/* NNV: revist, it may not be smd version */
511static int debug_read_smd_version(char *buf, int max)
512{
513 uint32_t *smd_ver;
514 uint32_t n, version, i = 0;
515
516 smd_ver = smem_alloc(SMEM_VERSION_SMD, 32 * sizeof(uint32_t));
517
518 if (smd_ver)
519 for (n = 0; n < 32; n++) {
520 version = smd_ver[n];
521 i += scnprintf(buf + i, max - i,
522 "entry %d: %d.%d\n", n,
523 version >> 16,
524 version & 0xffff);
525 }
526
527 return i;
Brian Swetland03e00cd2009-07-01 17:58:37 -0700528}
529
530static int debug_read_build_id(char *buf, int max)
531{
532 unsigned size;
533 void *data;
534
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700535 data = smem_get_entry(SMEM_HW_SW_BUILD_ID, &size);
Brian Swetland03e00cd2009-07-01 17:58:37 -0700536 if (!data)
537 return 0;
538
539 if (size >= max)
540 size = max;
541 memcpy(buf, data, size);
542
543 return size;
544}
545
546static int debug_read_alloc_tbl(char *buf, int max)
547{
548 struct smd_alloc_elm *shared;
549 int n, i = 0;
550
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700551 shared = smem_find(ID_CH_ALLOC_TBL, sizeof(struct smd_alloc_elm[64]));
552
553 if (!shared)
554 return 0;
Brian Swetland03e00cd2009-07-01 17:58:37 -0700555
556 for (n = 0; n < 64; n++) {
Brian Swetland03e00cd2009-07-01 17:58:37 -0700557 i += scnprintf(buf + i, max - i,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700558 "name=%s cid=%d ch type=%d "
559 "xfer type=%d ref_count=%d\n",
560 shared[n].name,
561 shared[n].cid,
562 SMD_CHANNEL_TYPE(shared[n].type),
563 SMD_XFER_TYPE(shared[n].type),
564 shared[n].ref_count);
Brian Swetland03e00cd2009-07-01 17:58:37 -0700565 }
566
567 return i;
568}
569
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700570static int debug_read_intr_mask(char *buf, int max)
571{
572 uint32_t *smsm;
573 int m, n, i = 0;
574
575 smsm = smem_alloc(SMEM_SMSM_CPU_INTR_MASK,
576 SMSM_NUM_ENTRIES * SMSM_NUM_HOSTS * sizeof(uint32_t));
577
578 if (smsm)
579 for (m = 0; m < SMSM_NUM_ENTRIES; m++) {
580 i += scnprintf(buf + i, max - i, "entry %d:", m);
581 for (n = 0; n < SMSM_NUM_HOSTS; n++)
582 i += scnprintf(buf + i, max - i,
583 " host %d: 0x%08x",
584 n, smsm[m * SMSM_NUM_HOSTS + n]);
585 i += scnprintf(buf + i, max - i, "\n");
586 }
587
588 return i;
589}
590
591static int debug_read_intr_mux(char *buf, int max)
592{
593 uint32_t *smsm;
594 int n, i = 0;
595
596 smsm = smem_alloc(SMEM_SMD_SMSM_INTR_MUX,
597 SMSM_NUM_INTR_MUX * sizeof(uint32_t));
598
599 if (smsm)
600 for (n = 0; n < SMSM_NUM_INTR_MUX; n++)
601 i += scnprintf(buf + i, max - i, "entry %d: %d\n",
602 n, smsm[n]);
603
604 return i;
605}
606
Brian Swetland03e00cd2009-07-01 17:58:37 -0700607#define DEBUG_BUFMAX 4096
608static char debug_buffer[DEBUG_BUFMAX];
609
610static ssize_t debug_read(struct file *file, char __user *buf,
611 size_t count, loff_t *ppos)
612{
613 int (*fill)(char *buf, int max) = file->private_data;
614 int bsize = fill(debug_buffer, DEBUG_BUFMAX);
615 return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
616}
617
618static int debug_open(struct inode *inode, struct file *file)
619{
620 file->private_data = inode->i_private;
621 return 0;
622}
623
624static const struct file_operations debug_ops = {
625 .read = debug_read,
626 .open = debug_open,
627};
628
629static void debug_create(const char *name, mode_t mode,
630 struct dentry *dent,
631 int (*fill)(char *buf, int max))
632{
633 debugfs_create_file(name, mode, dent, fill, &debug_ops);
634}
635
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700636static int __init smd_debugfs_init(void)
Brian Swetland03e00cd2009-07-01 17:58:37 -0700637{
638 struct dentry *dent;
639
640 dent = debugfs_create_dir("smd", 0);
641 if (IS_ERR(dent))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700642 return PTR_ERR(dent);
Brian Swetland03e00cd2009-07-01 17:58:37 -0700643
644 debug_create("ch", 0444, dent, debug_read_ch);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700645 debug_create("diag", 0444, dent, debug_read_diag_msg);
Brian Swetland03e00cd2009-07-01 17:58:37 -0700646 debug_create("mem", 0444, dent, debug_read_mem);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700647 debug_create("version", 0444, dent, debug_read_smd_version);
Brian Swetland03e00cd2009-07-01 17:58:37 -0700648 debug_create("tbl", 0444, dent, debug_read_alloc_tbl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700649 debug_create("modem_err", 0444, dent, debug_modem_err);
650 debug_create("modem_err_f3", 0444, dent, debug_modem_err_f3);
651 debug_create("print_diag", 0444, dent, debug_diag);
652 debug_create("print_f3", 0444, dent, debug_f3);
653
654 /* NNV: this is google only stuff */
Brian Swetland03e00cd2009-07-01 17:58:37 -0700655 debug_create("build", 0444, dent, debug_read_build_id);
Daniel Walker869a2a02010-04-23 11:04:14 -0700656
657 return 0;
Brian Swetland03e00cd2009-07-01 17:58:37 -0700658}
659
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700660static int __init smsm_debugfs_init(void)
661{
662 struct dentry *dent;
663
664 dent = debugfs_create_dir("smsm", 0);
665 if (IS_ERR(dent))
666 return PTR_ERR(dent);
667
668 debug_create("state", 0444, dent, debug_read_smsm_state);
669 debug_create("intr_mask", 0444, dent, debug_read_intr_mask);
670 debug_create("intr_mux", 0444, dent, debug_read_intr_mux);
671 debug_create("version", 0444, dent, debug_read_smem_version);
672 debug_create("smsm_test", 0444, dent, debug_test_smsm);
673
674 return 0;
675}
676
Brian Swetland03e00cd2009-07-01 17:58:37 -0700677late_initcall(smd_debugfs_init);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700678late_initcall(smsm_debugfs_init);
Brian Swetland03e00cd2009-07-01 17:58:37 -0700679#endif
680
681
682#define MAX_NUM_SLEEP_CLIENTS 64
683#define MAX_SLEEP_NAME_LEN 8
684
685#define NUM_GPIO_INT_REGISTERS 6
686#define GPIO_SMEM_NUM_GROUPS 2
687#define GPIO_SMEM_MAX_PC_INTERRUPTS 8
688
689struct tramp_gpio_save {
690 unsigned int enable;
691 unsigned int detect;
692 unsigned int polarity;
693};
694
695struct tramp_gpio_smem {
696 uint16_t num_fired[GPIO_SMEM_NUM_GROUPS];
697 uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS];
698 uint32_t enabled[NUM_GPIO_INT_REGISTERS];
699 uint32_t detection[NUM_GPIO_INT_REGISTERS];
700 uint32_t polarity[NUM_GPIO_INT_REGISTERS];
701};
702
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700703/*
704 * Print debug information on shared memory sleep variables
705 */
706void smsm_print_sleep_info(uint32_t sleep_delay, uint32_t sleep_limit,
707 uint32_t irq_mask, uint32_t wakeup_reason, uint32_t pending_irqs)
Brian Swetland03e00cd2009-07-01 17:58:37 -0700708{
709 unsigned long flags;
710 uint32_t *ptr;
711 struct tramp_gpio_smem *gpio;
Brian Swetland03e00cd2009-07-01 17:58:37 -0700712
713 spin_lock_irqsave(&smem_lock, flags);
714
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700715 pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", sleep_delay);
716 pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", sleep_limit);
Brian Swetland03e00cd2009-07-01 17:58:37 -0700717
718 ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr));
719 if (ptr)
720 pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700721 else
722 pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: missing\n");
Brian Swetland03e00cd2009-07-01 17:58:37 -0700723
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700724 pr_info("SMEM_SMSM_INT_INFO %x %x %x\n",
725 irq_mask, pending_irqs, wakeup_reason);
Brian Swetland03e00cd2009-07-01 17:58:37 -0700726
727 gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio));
728 if (gpio) {
729 int i;
730 for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++)
731 pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n",
732 i, gpio->enabled[i], gpio->detection[i],
733 gpio->polarity[i]);
734
735 for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++)
736 pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n",
737 i, gpio->num_fired[i], gpio->fired[i][0],
738 gpio->fired[i][1]);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700739 } else
740 pr_info("SMEM_GPIO_INT: missing\n");
741
Brian Swetland03e00cd2009-07-01 17:58:37 -0700742 spin_unlock_irqrestore(&smem_lock, flags);
743}