blob: a7f29e63e214c22af31289a6158575a3affb2407 [file] [log] [blame]
Mohit Aggarwal86731ea2017-05-25 20:21:12 +05301/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#ifdef CONFIG_DEBUG_FS
14
15#include <linux/slab.h>
16#include <linux/debugfs.h>
17#include <linux/atomic.h>
18#include <linux/uaccess.h>
19#include "diagchar.h"
20#include "diagfwd.h"
21#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
22#include "diagfwd_bridge.h"
23#endif
24#ifdef CONFIG_USB_QCOM_DIAG_BRIDGE
25#include "diagfwd_hsic.h"
26#include "diagfwd_smux.h"
27#endif
28#ifdef CONFIG_MSM_MHI
29#include "diagfwd_mhi.h"
30#endif
31#include "diagmem.h"
32#include "diag_dci.h"
33#include "diag_usb.h"
34#include "diagfwd_peripheral.h"
Hardik Aryad6da1cb2017-11-23 20:40:55 +053035#include "diagfwd_smd.h"
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -070036#include "diagfwd_socket.h"
37#include "diagfwd_glink.h"
38#include "diag_debugfs.h"
39#include "diag_ipc_logging.h"
40
41#define DEBUG_BUF_SIZE 4096
42static struct dentry *diag_dbgfs_dent;
43static int diag_dbgfs_table_index;
44static int diag_dbgfs_mempool_index;
45static int diag_dbgfs_usbinfo_index;
Hardik Aryad6da1cb2017-11-23 20:40:55 +053046static int diag_dbgfs_smdinfo_index;
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -070047static int diag_dbgfs_socketinfo_index;
48static int diag_dbgfs_glinkinfo_index;
49static int diag_dbgfs_hsicinfo_index;
50static int diag_dbgfs_mhiinfo_index;
51static int diag_dbgfs_bridgeinfo_index;
52static int diag_dbgfs_finished;
53static int diag_dbgfs_dci_data_index;
54static int diag_dbgfs_dci_finished;
Sreelakshmi Gownipalli13e83672017-10-09 12:59:56 -070055static struct mutex diag_dci_dbgfs_mutex;
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -070056static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
57 size_t count, loff_t *ppos)
58{
59 char *buf;
60 int ret, i;
61 unsigned int buf_size;
62
63 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
64 if (!buf)
65 return -ENOMEM;
66 buf_size = ksize(buf);
67 ret = scnprintf(buf, buf_size,
68 "CPU Tools ID: %d\n"
69 "Check Polling Response: %d\n"
70 "Polling Registered: %d\n"
71 "Uses Device Tree: %d\n"
72 "Apps Supports Separate CMDRSP: %d\n"
73 "Apps Supports HDLC Encoding: %d\n"
Manoj Prabhu B571cf422017-08-08 19:01:41 +053074 "Apps Supports Header Untagging: %d\n"
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -070075 "Apps Supports Sockets: %d\n"
76 "Logging Mode: %d\n"
77 "RSP Buffer is Busy: %d\n"
78 "HDLC Disabled: %d\n"
79 "Time Sync Enabled: %d\n"
80 "MD session mode: %d\n"
81 "MD session mask: %d\n"
Manoj Prabhu Bcba38ed2017-11-08 20:24:46 +053082 "Uses Time API: %d\n"
83 "Supports PD buffering: %d\n",
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -070084 chk_config_get_id(),
85 chk_polling_response(),
86 driver->polling_reg_flag,
87 driver->use_device_tree,
88 driver->supports_separate_cmdrsp,
89 driver->supports_apps_hdlc_encoding,
Manoj Prabhu B571cf422017-08-08 19:01:41 +053090 driver->supports_apps_header_untagging,
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -070091 driver->supports_sockets,
92 driver->logging_mode,
93 driver->rsp_buf_busy,
94 driver->hdlc_disabled,
95 driver->time_sync_enabled,
96 driver->md_session_mode,
97 driver->md_session_mask,
Manoj Prabhu Bcba38ed2017-11-08 20:24:46 +053098 driver->uses_time_api,
99 driver->supports_pd_buffering);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700100
101 for (i = 0; i < NUM_PERIPHERALS; i++) {
102 ret += scnprintf(buf+ret, buf_size-ret,
Manoj Prabhu Bcba38ed2017-11-08 20:24:46 +0530103 "p: %s Feature: %02x %02x |%c%c%c%c%c%c%c%c%c%c|\n",
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700104 PERIPHERAL_STRING(i),
105 driver->feature[i].feature_mask[0],
106 driver->feature[i].feature_mask[1],
107 driver->feature[i].rcvd_feature_mask ? 'F':'f',
108 driver->feature[i].separate_cmd_rsp ? 'C':'c',
109 driver->feature[i].encode_hdlc ? 'H':'h',
110 driver->feature[i].peripheral_buffering ? 'B':'b',
111 driver->feature[i].mask_centralization ? 'M':'m',
Manoj Prabhu Bcba38ed2017-11-08 20:24:46 +0530112 driver->feature[i].pd_buffering ? 'P':'p',
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700113 driver->feature[i].stm_support ? 'Q':'q',
114 driver->feature[i].sockets_enabled ? 'S':'s',
Manoj Prabhu B571cf422017-08-08 19:01:41 +0530115 driver->feature[i].sent_feature_mask ? 'T':'t',
116 driver->feature[i].untag_header ? 'U':'u');
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700117 }
118
119#ifdef CONFIG_DIAG_OVER_USB
120 ret += scnprintf(buf+ret, buf_size-ret,
121 "USB Connected: %d\n",
122 driver->usb_connected);
123#endif
124
125 for (i = 0; i < DIAG_NUM_PROC; i++) {
126 ret += scnprintf(buf+ret, buf_size-ret,
127 "Real Time Mode: %d: %d\n", i,
128 driver->real_time_mode[i]);
129 }
130
131 ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
132
133 kfree(buf);
134 return ret;
135}
136
137static ssize_t diag_dbgfs_read_dcistats(struct file *file,
138 char __user *ubuf, size_t count, loff_t *ppos)
139{
140 char *buf = NULL;
141 unsigned int bytes_remaining, bytes_written = 0;
142 unsigned int bytes_in_buf = 0, i = 0;
143 struct diag_dci_data_info *temp_data = dci_traffic;
144 unsigned int buf_size;
145
146 buf_size = (count > DEBUG_BUF_SIZE) ? DEBUG_BUF_SIZE : count;
147
148 if (diag_dbgfs_dci_finished) {
149 diag_dbgfs_dci_finished = 0;
150 return 0;
151 }
152
153 buf = kcalloc(buf_size, sizeof(char), GFP_KERNEL);
154 if (ZERO_OR_NULL_PTR(buf))
155 return -ENOMEM;
156
157 buf_size = ksize(buf);
158 bytes_remaining = buf_size;
159
Sreelakshmi Gownipalli13e83672017-10-09 12:59:56 -0700160 mutex_lock(&diag_dci_dbgfs_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700161 if (diag_dbgfs_dci_data_index == 0) {
162 bytes_written =
163 scnprintf(buf, buf_size,
164 "number of clients: %d\n"
165 "dci proc active: %d\n"
166 "dci real time vote: %d\n",
167 driver->num_dci_client,
168 (driver->proc_active_mask & DIAG_PROC_DCI) ? 1 : 0,
169 (driver->proc_rt_vote_mask[DIAG_LOCAL_PROC] &
170 DIAG_PROC_DCI) ? 1 : 0);
171 bytes_in_buf += bytes_written;
172 bytes_remaining -= bytes_written;
173#ifdef CONFIG_DIAG_OVER_USB
174 bytes_written = scnprintf(buf+bytes_in_buf, bytes_remaining,
175 "usb_connected: %d\n",
176 driver->usb_connected);
177 bytes_in_buf += bytes_written;
178 bytes_remaining -= bytes_written;
179#endif
180 bytes_written = scnprintf(buf+bytes_in_buf,
181 bytes_remaining,
182 "dci power: active, relax: %lu, %lu\n",
183 driver->diag_dev->power.wakeup->
184 active_count,
185 driver->diag_dev->
186 power.wakeup->relax_count);
187 bytes_in_buf += bytes_written;
188 bytes_remaining -= bytes_written;
189
190 }
191 temp_data += diag_dbgfs_dci_data_index;
192 for (i = diag_dbgfs_dci_data_index; i < DIAG_DCI_DEBUG_CNT; i++) {
193 if (temp_data->iteration != 0) {
194 bytes_written = scnprintf(
195 buf + bytes_in_buf, bytes_remaining,
196 "i %-5ld\t"
197 "s %-5d\t"
198 "p %-5d\t"
199 "r %-5d\t"
200 "c %-5d\t"
201 "t %-15s\n",
202 temp_data->iteration,
203 temp_data->data_size,
204 temp_data->peripheral,
205 temp_data->proc,
206 temp_data->ch_type,
207 temp_data->time_stamp);
208 bytes_in_buf += bytes_written;
209 bytes_remaining -= bytes_written;
210 /* Check if there is room for another entry */
211 if (bytes_remaining < bytes_written)
212 break;
213 }
214 temp_data++;
215 }
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700216 diag_dbgfs_dci_data_index = (i >= DIAG_DCI_DEBUG_CNT) ? 0 : i + 1;
Sreelakshmi Gownipalli13e83672017-10-09 12:59:56 -0700217 mutex_unlock(&diag_dci_dbgfs_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700218 bytes_written = simple_read_from_buffer(ubuf, count, ppos, buf,
219 bytes_in_buf);
220 kfree(buf);
221 diag_dbgfs_dci_finished = 1;
222 return bytes_written;
223}
224
225static ssize_t diag_dbgfs_read_power(struct file *file, char __user *ubuf,
226 size_t count, loff_t *ppos)
227{
228 char *buf;
229 int ret;
230 unsigned int buf_size;
231
232 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
233 if (!buf)
234 return -ENOMEM;
235
236 buf_size = ksize(buf);
237 ret = scnprintf(buf, buf_size,
238 "DCI reference count: %d\n"
239 "DCI copy count: %d\n"
240 "DCI Client Count: %d\n\n"
241 "Memory Device reference count: %d\n"
242 "Memory Device copy count: %d\n"
243 "Logging mode: %d\n\n"
244 "Wakeup source active count: %lu\n"
245 "Wakeup source relax count: %lu\n\n",
246 driver->dci_ws.ref_count,
247 driver->dci_ws.copy_count,
248 driver->num_dci_client,
249 driver->md_ws.ref_count,
250 driver->md_ws.copy_count,
251 driver->logging_mode,
252 driver->diag_dev->power.wakeup->active_count,
253 driver->diag_dev->power.wakeup->relax_count);
254
255 ret = simple_read_from_buffer(ubuf, count, ppos, buf, ret);
256
257 kfree(buf);
258 return ret;
259}
260
261static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
262 size_t count, loff_t *ppos)
263{
264 char *buf;
265 int ret = 0;
266 int i = 0;
267 int is_polling = 0;
268 unsigned int bytes_remaining;
269 unsigned int bytes_in_buffer = 0;
270 unsigned int bytes_written;
271 unsigned int buf_size;
272 struct list_head *start;
273 struct list_head *temp;
274 struct diag_cmd_reg_t *item = NULL;
275
Mohit Aggarwal86731ea2017-05-25 20:21:12 +0530276 mutex_lock(&driver->cmd_reg_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700277 if (diag_dbgfs_table_index == driver->cmd_reg_count) {
278 diag_dbgfs_table_index = 0;
Mohit Aggarwal86731ea2017-05-25 20:21:12 +0530279 mutex_unlock(&driver->cmd_reg_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700280 return 0;
281 }
282
283 buf_size = (count > DEBUG_BUF_SIZE) ? DEBUG_BUF_SIZE : count;
284
285 buf = kcalloc(buf_size, sizeof(char), GFP_KERNEL);
286 if (ZERO_OR_NULL_PTR(buf)) {
287 pr_err("diag: %s, Error allocating memory\n", __func__);
Mohit Aggarwal86731ea2017-05-25 20:21:12 +0530288 mutex_unlock(&driver->cmd_reg_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700289 return -ENOMEM;
290 }
291 buf_size = ksize(buf);
292 bytes_remaining = buf_size;
293
294 if (diag_dbgfs_table_index == 0) {
295 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
296 "Client ids: Modem: %d, LPASS: %d, WCNSS: %d, SLPI: %d, APPS: %d\n",
297 PERIPHERAL_MODEM, PERIPHERAL_LPASS,
298 PERIPHERAL_WCNSS, PERIPHERAL_SENSORS,
299 APPS_DATA);
300 bytes_in_buffer += bytes_written;
301 bytes_remaining -= bytes_written;
302 }
303
304 list_for_each_safe(start, temp, &driver->cmd_reg_list) {
305 item = list_entry(start, struct diag_cmd_reg_t, link);
306 if (i < diag_dbgfs_table_index) {
307 i++;
308 continue;
309 }
310
311 is_polling = diag_cmd_chk_polling(&item->entry);
312 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
313 "i: %3d, cmd_code: %4x, subsys_id: %4x, cmd_code_lo: %4x, cmd_code_hi: %4x, proc: %d, process_id: %5d %s\n",
314 i++,
315 item->entry.cmd_code,
316 item->entry.subsys_id,
317 item->entry.cmd_code_lo,
318 item->entry.cmd_code_hi,
319 item->proc,
320 item->pid,
321 (is_polling == DIAG_CMD_POLLING) ?
322 "<-- Polling Cmd" : "");
323
324 bytes_in_buffer += bytes_written;
325
326 /* Check if there is room to add another table entry */
327 bytes_remaining = buf_size - bytes_in_buffer;
328
329 if (bytes_remaining < bytes_written)
330 break;
331 }
332 diag_dbgfs_table_index = i;
Mohit Aggarwal86731ea2017-05-25 20:21:12 +0530333 mutex_unlock(&driver->cmd_reg_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700334
335 *ppos = 0;
336 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
337
338 kfree(buf);
339 return ret;
340}
341
342static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf,
343 size_t count, loff_t *ppos)
344{
345 char *buf = NULL;
346 int ret = 0;
347 int i = 0;
348 unsigned int buf_size;
349 unsigned int bytes_remaining = 0;
350 unsigned int bytes_written = 0;
351 unsigned int bytes_in_buffer = 0;
352 struct diag_mempool_t *mempool = NULL;
353
354 if (diag_dbgfs_mempool_index >= NUM_MEMORY_POOLS) {
355 /* Done. Reset to prepare for future requests */
356 diag_dbgfs_mempool_index = 0;
357 return 0;
358 }
359
360 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
361 if (ZERO_OR_NULL_PTR(buf)) {
362 pr_err("diag: %s, Error allocating memory\n", __func__);
363 return -ENOMEM;
364 }
365
366 buf_size = ksize(buf);
367 bytes_remaining = buf_size;
368 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
369 "%-24s\t"
370 "%-10s\t"
371 "%-5s\t"
372 "%-5s\t"
373 "%-5s\n",
374 "POOL", "HANDLE", "COUNT", "SIZE", "ITEMSIZE");
375 bytes_in_buffer += bytes_written;
376 bytes_remaining = buf_size - bytes_in_buffer;
377
378 for (i = diag_dbgfs_mempool_index; i < NUM_MEMORY_POOLS; i++) {
379 mempool = &diag_mempools[i];
380 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
381 "%-24s\t"
382 "%-10p\t"
383 "%-5d\t"
384 "%-5d\t"
385 "%-5d\n",
386 mempool->name,
387 mempool->pool,
388 mempool->count,
389 mempool->poolsize,
390 mempool->itemsize);
391 bytes_in_buffer += bytes_written;
392
393 /* Check if there is room to add another table entry */
394 bytes_remaining = buf_size - bytes_in_buffer;
395
396 if (bytes_remaining < bytes_written)
397 break;
398 }
399 diag_dbgfs_mempool_index = i+1;
400 *ppos = 0;
401 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
402
403 kfree(buf);
404 return ret;
405}
406
407static ssize_t diag_dbgfs_read_usbinfo(struct file *file, char __user *ubuf,
408 size_t count, loff_t *ppos)
409{
410 char *buf = NULL;
411 int ret = 0;
412 int i = 0;
413 unsigned int buf_size;
414 unsigned int bytes_remaining = 0;
415 unsigned int bytes_written = 0;
416 unsigned int bytes_in_buffer = 0;
417 struct diag_usb_info *usb_info = NULL;
418
419 if (diag_dbgfs_usbinfo_index >= NUM_DIAG_USB_DEV) {
420 /* Done. Reset to prepare for future requests */
421 diag_dbgfs_usbinfo_index = 0;
422 return 0;
423 }
424
425 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
426 if (ZERO_OR_NULL_PTR(buf)) {
427 pr_err("diag: %s, Error allocating memory\n", __func__);
428 return -ENOMEM;
429 }
430
431 buf_size = ksize(buf);
432 bytes_remaining = buf_size;
433 for (i = diag_dbgfs_usbinfo_index; i < NUM_DIAG_USB_DEV; i++) {
434 usb_info = &diag_usb[i];
435 if (!usb_info->enabled)
436 continue;
437 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
438 "id: %d\n"
439 "name: %s\n"
440 "hdl: %pK\n"
441 "connected: %d\n"
442 "diag state: %d\n"
443 "enabled: %d\n"
444 "mempool: %s\n"
445 "read pending: %d\n"
446 "read count: %lu\n"
447 "write count: %lu\n"
448 "read work pending: %d\n"
449 "read done work pending: %d\n"
450 "connect work pending: %d\n"
451 "disconnect work pending: %d\n"
452 "max size supported: %d\n\n",
453 usb_info->id,
454 usb_info->name,
455 usb_info->hdl,
456 atomic_read(&usb_info->connected),
457 atomic_read(&usb_info->diag_state),
458 usb_info->enabled,
459 DIAG_MEMPOOL_GET_NAME(usb_info->mempool),
460 atomic_read(&usb_info->read_pending),
461 usb_info->read_cnt,
462 usb_info->write_cnt,
463 work_pending(&usb_info->read_work),
464 work_pending(&usb_info->read_done_work),
465 work_pending(&usb_info->connect_work),
466 work_pending(&usb_info->disconnect_work),
467 usb_info->max_size);
468 bytes_in_buffer += bytes_written;
469
470 /* Check if there is room to add another table entry */
471 bytes_remaining = buf_size - bytes_in_buffer;
472
473 if (bytes_remaining < bytes_written)
474 break;
475 }
476 diag_dbgfs_usbinfo_index = i+1;
477 *ppos = 0;
478 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
479
480 kfree(buf);
481 return ret;
482}
483
Hardik Aryad6da1cb2017-11-23 20:40:55 +0530484#ifdef CONFIG_DIAG_USES_SMD
485static ssize_t diag_dbgfs_read_smdinfo(struct file *file, char __user *ubuf,
486 size_t count, loff_t *ppos)
487{
488 char *buf = NULL;
489 int ret = 0;
490 int i = 0;
491 int j = 0;
492 unsigned int buf_size;
493 unsigned int bytes_remaining = 0;
494 unsigned int bytes_written = 0;
495 unsigned int bytes_in_buffer = 0;
496 struct diag_smd_info *smd_info = NULL;
497 struct diagfwd_info *fwd_ctxt = NULL;
498
499 if (diag_dbgfs_smdinfo_index >= NUM_PERIPHERALS) {
500 /* Done. Reset to prepare for future requests */
501 diag_dbgfs_smdinfo_index = 0;
502 return 0;
503 }
504
505 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
506 if (!buf)
507 return -ENOMEM;
508
509 buf_size = DEBUG_BUF_SIZE;
510 bytes_remaining = buf_size;
511 for (i = 0; i < NUM_TYPES; i++) {
512 for (j = 0; j < NUM_PERIPHERALS; j++) {
513 switch (i) {
514 case TYPE_DATA:
515 smd_info = &smd_data[j];
516 break;
517 case TYPE_CNTL:
518 smd_info = &smd_cntl[j];
519 break;
520 case TYPE_DCI:
521 smd_info = &smd_dci[j];
522 break;
523 case TYPE_CMD:
524 smd_info = &smd_cmd[j];
525 break;
526 case TYPE_DCI_CMD:
527 smd_info = &smd_dci_cmd[j];
528 break;
529 default:
530 return -EINVAL;
531 }
532
533 fwd_ctxt = (struct diagfwd_info *)(smd_info->fwd_ctxt);
534
535 bytes_written = scnprintf(buf+bytes_in_buffer,
536 bytes_remaining,
537 "name\t\t:\t%s\n"
538 "hdl\t\t:\t%pK\n"
539 "inited\t\t:\t%d\n"
540 "opened\t\t:\t%d\n"
541 "diag_state\t:\t%d\n"
542 "fifo size\t:\t%d\n"
543 "open pending\t:\t%d\n"
544 "close pending\t:\t%d\n"
545 "read pending\t:\t%d\n"
546 "buf_1 busy\t:\t%d\n"
547 "buf_2 busy\t:\t%d\n"
548 "bytes read\t:\t%lu\n"
549 "bytes written\t:\t%lu\n"
550 "fwd inited\t:\t%d\n"
551 "fwd opened\t:\t%d\n"
552 "fwd ch_open\t:\t%d\n\n",
553 smd_info->name,
554 smd_info->hdl,
555 smd_info->inited,
556 atomic_read(&smd_info->opened),
557 atomic_read(&smd_info->diag_state),
558 smd_info->fifo_size,
559 work_pending(&smd_info->open_work),
560 work_pending(&smd_info->close_work),
561 work_pending(&smd_info->read_work),
562 (fwd_ctxt && fwd_ctxt->buf_1) ?
563 atomic_read(&fwd_ctxt->buf_1->in_busy) : -1,
564 (fwd_ctxt && fwd_ctxt->buf_2) ?
565 atomic_read(&fwd_ctxt->buf_2->in_busy) : -1,
566 (fwd_ctxt) ? fwd_ctxt->read_bytes : 0,
567 (fwd_ctxt) ? fwd_ctxt->write_bytes : 0,
568 (fwd_ctxt) ? fwd_ctxt->inited : -1,
569 (fwd_ctxt) ?
570 atomic_read(&fwd_ctxt->opened) : -1,
571 (fwd_ctxt) ? fwd_ctxt->ch_open : -1);
572 bytes_in_buffer += bytes_written;
573
574 /* Check if there is room to add another table entry */
575 bytes_remaining = buf_size - bytes_in_buffer;
576
577 if (bytes_remaining < bytes_written)
578 break;
579 }
580 }
581 diag_dbgfs_smdinfo_index = i+1;
582 *ppos = 0;
583 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
584
585 kfree(buf);
586 return ret;
587}
588#endif
589
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -0700590static ssize_t diag_dbgfs_read_socketinfo(struct file *file, char __user *ubuf,
591 size_t count, loff_t *ppos)
592{
593 char *buf = NULL;
594 int ret = 0;
595 int i = 0;
596 int j = 0;
597 unsigned int buf_size;
598 unsigned int bytes_remaining = 0;
599 unsigned int bytes_written = 0;
600 unsigned int bytes_in_buffer = 0;
601 struct diag_socket_info *info = NULL;
602 struct diagfwd_info *fwd_ctxt = NULL;
603
604 if (diag_dbgfs_socketinfo_index >= NUM_PERIPHERALS) {
605 /* Done. Reset to prepare for future requests */
606 diag_dbgfs_socketinfo_index = 0;
607 return 0;
608 }
609
610 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
611 if (ZERO_OR_NULL_PTR(buf)) {
612 pr_err("diag: %s, Error allocating memory\n", __func__);
613 return -ENOMEM;
614 }
615
616 buf_size = ksize(buf);
617 bytes_remaining = buf_size;
618 for (i = 0; i < NUM_TYPES; i++) {
619 for (j = 0; j < NUM_PERIPHERALS; j++) {
620 switch (i) {
621 case TYPE_DATA:
622 info = &socket_data[j];
623 break;
624 case TYPE_CNTL:
625 info = &socket_cntl[j];
626 break;
627 case TYPE_DCI:
628 info = &socket_dci[j];
629 break;
630 case TYPE_CMD:
631 info = &socket_cmd[j];
632 break;
633 case TYPE_DCI_CMD:
634 info = &socket_dci_cmd[j];
635 break;
636 default:
637 return -EINVAL;
638 }
639
640 fwd_ctxt = (struct diagfwd_info *)(info->fwd_ctxt);
641
642 bytes_written = scnprintf(buf+bytes_in_buffer,
643 bytes_remaining,
644 "name\t\t:\t%s\n"
645 "hdl\t\t:\t%pK\n"
646 "inited\t\t:\t%d\n"
647 "opened\t\t:\t%d\n"
648 "diag_state\t:\t%d\n"
649 "buf_1 busy\t:\t%d\n"
650 "buf_2 busy\t:\t%d\n"
651 "flow ctrl count\t:\t%d\n"
652 "data_ready\t:\t%d\n"
653 "init pending\t:\t%d\n"
654 "read pending\t:\t%d\n"
655 "bytes read\t:\t%lu\n"
656 "bytes written\t:\t%lu\n"
657 "fwd inited\t:\t%d\n"
658 "fwd opened\t:\t%d\n"
659 "fwd ch_open\t:\t%d\n\n",
660 info->name,
661 info->hdl,
662 info->inited,
663 atomic_read(&info->opened),
664 atomic_read(&info->diag_state),
665 (fwd_ctxt && fwd_ctxt->buf_1) ?
666 atomic_read(&fwd_ctxt->buf_1->in_busy) : -1,
667 (fwd_ctxt && fwd_ctxt->buf_2) ?
668 atomic_read(&fwd_ctxt->buf_2->in_busy) : -1,
669 atomic_read(&info->flow_cnt),
670 info->data_ready,
671 work_pending(&info->init_work),
672 work_pending(&info->read_work),
673 (fwd_ctxt) ? fwd_ctxt->read_bytes : 0,
674 (fwd_ctxt) ? fwd_ctxt->write_bytes : 0,
675 (fwd_ctxt) ? fwd_ctxt->inited : -1,
676 (fwd_ctxt) ?
677 atomic_read(&fwd_ctxt->opened) : -1,
678 (fwd_ctxt) ? fwd_ctxt->ch_open : -1);
679 bytes_in_buffer += bytes_written;
680
681 /* Check if there is room to add another table entry */
682 bytes_remaining = buf_size - bytes_in_buffer;
683
684 if (bytes_remaining < bytes_written)
685 break;
686 }
687 }
688 diag_dbgfs_socketinfo_index = i+1;
689 *ppos = 0;
690 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
691
692 kfree(buf);
693 return ret;
694}
695
696static ssize_t diag_dbgfs_read_glinkinfo(struct file *file, char __user *ubuf,
697 size_t count, loff_t *ppos)
698{
699 char *buf = NULL;
700 int ret = 0;
701 int i = 0;
702 int j = 0;
703 unsigned int buf_size;
704 unsigned int bytes_remaining = 0;
705 unsigned int bytes_written = 0;
706 unsigned int bytes_in_buffer = 0;
707 struct diag_glink_info *info = NULL;
708 struct diagfwd_info *fwd_ctxt = NULL;
709
710 if (diag_dbgfs_glinkinfo_index >= NUM_PERIPHERALS) {
711 /* Done. Reset to prepare for future requests */
712 diag_dbgfs_socketinfo_index = 0;
713 return 0;
714 }
715
716 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
717 if (!buf)
718 return -ENOMEM;
719
720 buf_size = ksize(buf);
721 bytes_remaining = buf_size;
722 for (i = 0; i < NUM_TYPES; i++) {
723 for (j = 0; j < NUM_PERIPHERALS; j++) {
724 switch (i) {
725 case TYPE_DATA:
726 info = &glink_data[j];
727 break;
728 case TYPE_CNTL:
729 info = &glink_cntl[j];
730 break;
731 case TYPE_DCI:
732 info = &glink_dci[j];
733 break;
734 case TYPE_CMD:
735 info = &glink_cmd[j];
736 break;
737 case TYPE_DCI_CMD:
738 info = &glink_dci_cmd[j];
739 break;
740 default:
741 return -EINVAL;
742 }
743
744 fwd_ctxt = (struct diagfwd_info *)(info->fwd_ctxt);
745
746 bytes_written = scnprintf(buf+bytes_in_buffer,
747 bytes_remaining,
748 "name\t\t:\t%s\n"
749 "hdl\t\t:\t%pK\n"
750 "inited\t\t:\t%d\n"
751 "opened\t\t:\t%d\n"
752 "diag_state\t:\t%d\n"
753 "buf_1 busy\t:\t%d\n"
754 "buf_2 busy\t:\t%d\n"
755 "tx_intent_ready\t:\t%d\n"
756 "open pending\t:\t%d\n"
757 "close pending\t:\t%d\n"
758 "read pending\t:\t%d\n"
759 "bytes read\t:\t%lu\n"
760 "bytes written\t:\t%lu\n"
761 "fwd inited\t:\t%d\n"
762 "fwd opened\t:\t%d\n"
763 "fwd ch_open\t:\t%d\n\n",
764 info->name,
765 info->hdl,
766 info->inited,
767 atomic_read(&info->opened),
768 atomic_read(&info->diag_state),
769 (fwd_ctxt && fwd_ctxt->buf_1) ?
770 atomic_read(&fwd_ctxt->buf_1->in_busy) : -1,
771 (fwd_ctxt && fwd_ctxt->buf_2) ?
772 atomic_read(&fwd_ctxt->buf_2->in_busy) : -1,
773 atomic_read(&info->tx_intent_ready),
774 work_pending(&info->open_work),
775 work_pending(&info->close_work),
776 work_pending(&info->read_work),
777 (fwd_ctxt) ? fwd_ctxt->read_bytes : 0,
778 (fwd_ctxt) ? fwd_ctxt->write_bytes : 0,
779 (fwd_ctxt) ? fwd_ctxt->inited : -1,
780 (fwd_ctxt) ?
781 atomic_read(&fwd_ctxt->opened) : -1,
782 (fwd_ctxt) ? fwd_ctxt->ch_open : -1);
783 bytes_in_buffer += bytes_written;
784
785 /* Check if there is room to add another table entry */
786 bytes_remaining = buf_size - bytes_in_buffer;
787
788 if (bytes_remaining < bytes_written)
789 break;
790 }
791 }
792 diag_dbgfs_glinkinfo_index = i+1;
793 *ppos = 0;
794 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
795
796 kfree(buf);
797 return ret;
798}
799
800static ssize_t diag_dbgfs_write_debug(struct file *fp, const char __user *buf,
801 size_t count, loff_t *ppos)
802{
803 const int size = 10;
804 unsigned char cmd[size];
805 long value = 0;
806 int len = 0;
807
808 if (count < 1)
809 return -EINVAL;
810
811 len = (count < (size - 1)) ? count : size - 1;
812 if (copy_from_user(cmd, buf, len))
813 return -EFAULT;
814
815 cmd[len] = 0;
816 if (cmd[len-1] == '\n') {
817 cmd[len-1] = 0;
818 len--;
819 }
820
821 if (kstrtol(cmd, 10, &value))
822 return -EINVAL;
823
824 if (value < 0)
825 return -EINVAL;
826
827 diag_debug_mask = (uint16_t)value;
828 return count;
829}
830
831#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
832#ifdef CONFIG_USB_QCOM_DIAG_BRIDGE
833static ssize_t diag_dbgfs_read_hsicinfo(struct file *file, char __user *ubuf,
834 size_t count, loff_t *ppos)
835{
836 char *buf = NULL;
837 int ret = 0;
838 int i = 0;
839 unsigned int buf_size;
840 unsigned int bytes_remaining = 0;
841 unsigned int bytes_written = 0;
842 unsigned int bytes_in_buffer = 0;
843 struct diag_hsic_info *hsic_info = NULL;
844
845 if (diag_dbgfs_hsicinfo_index >= NUM_DIAG_USB_DEV) {
846 /* Done. Reset to prepare for future requests */
847 diag_dbgfs_hsicinfo_index = 0;
848 return 0;
849 }
850
851 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
852 if (ZERO_OR_NULL_PTR(buf)) {
853 pr_err("diag: %s, Error allocating memory\n", __func__);
854 return -ENOMEM;
855 }
856
857 buf_size = ksize(buf);
858 bytes_remaining = buf_size;
859 for (i = diag_dbgfs_hsicinfo_index; i < NUM_HSIC_DEV; i++) {
860 hsic_info = &diag_hsic[i];
861 if (!hsic_info->enabled)
862 continue;
863 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
864 "id: %d\n"
865 "name: %s\n"
866 "bridge index: %s\n"
867 "opened: %d\n"
868 "enabled: %d\n"
869 "suspended: %d\n"
870 "mempool: %s\n"
871 "read work pending: %d\n"
872 "open work pending: %d\n"
873 "close work pending: %d\n\n",
874 hsic_info->id,
875 hsic_info->name,
876 DIAG_BRIDGE_GET_NAME(hsic_info->dev_id),
877 hsic_info->opened,
878 hsic_info->enabled,
879 hsic_info->suspended,
880 DIAG_MEMPOOL_GET_NAME(hsic_info->mempool),
881 work_pending(&hsic_info->read_work),
882 work_pending(&hsic_info->open_work),
883 work_pending(&hsic_info->close_work));
884 bytes_in_buffer += bytes_written;
885
886 /* Check if there is room to add another table entry */
887 bytes_remaining = buf_size - bytes_in_buffer;
888
889 if (bytes_remaining < bytes_written)
890 break;
891 }
892 diag_dbgfs_hsicinfo_index = i+1;
893 *ppos = 0;
894 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
895
896 kfree(buf);
897 return ret;
898}
899
900const struct file_operations diag_dbgfs_hsicinfo_ops = {
901 .read = diag_dbgfs_read_hsicinfo,
902};
903#endif
904#ifdef CONFIG_MSM_MHI
905static ssize_t diag_dbgfs_read_mhiinfo(struct file *file, char __user *ubuf,
906 size_t count, loff_t *ppos)
907{
908 char *buf = NULL;
909 int ret = 0;
910 int i = 0;
911 unsigned int buf_size;
912 unsigned int bytes_remaining = 0;
913 unsigned int bytes_written = 0;
914 unsigned int bytes_in_buffer = 0;
915 struct diag_mhi_info *mhi_info = NULL;
916
917 if (diag_dbgfs_mhiinfo_index >= NUM_MHI_DEV) {
918 /* Done. Reset to prepare for future requests */
919 diag_dbgfs_mhiinfo_index = 0;
920 return 0;
921 }
922
923 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
924 if (ZERO_OR_NULL_PTR(buf)) {
925 pr_err("diag: %s, Error allocating memory\n", __func__);
926 return -ENOMEM;
927 }
928
929 buf_size = ksize(buf);
930 bytes_remaining = buf_size;
931 for (i = diag_dbgfs_mhiinfo_index; i < NUM_MHI_DEV; i++) {
932 mhi_info = &diag_mhi[i];
933 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
934 "id: %d\n"
935 "name: %s\n"
936 "bridge index: %s\n"
937 "mempool: %s\n"
938 "read ch opened: %d\n"
939 "read ch hdl: %pK\n"
940 "write ch opened: %d\n"
941 "write ch hdl: %pK\n"
942 "read work pending: %d\n"
943 "read done work pending: %d\n"
944 "open work pending: %d\n"
945 "close work pending: %d\n\n",
946 mhi_info->id,
947 mhi_info->name,
948 DIAG_BRIDGE_GET_NAME(mhi_info->dev_id),
949 DIAG_MEMPOOL_GET_NAME(mhi_info->mempool),
950 atomic_read(&mhi_info->read_ch.opened),
951 mhi_info->read_ch.hdl,
952 atomic_read(&mhi_info->write_ch.opened),
953 mhi_info->write_ch.hdl,
954 work_pending(&mhi_info->read_work),
955 work_pending(&mhi_info->read_done_work),
956 work_pending(&mhi_info->open_work),
957 work_pending(&mhi_info->close_work));
958 bytes_in_buffer += bytes_written;
959
960 /* Check if there is room to add another table entry */
961 bytes_remaining = buf_size - bytes_in_buffer;
962
963 if (bytes_remaining < bytes_written)
964 break;
965 }
966 diag_dbgfs_mhiinfo_index = i+1;
967 *ppos = 0;
968 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
969
970 kfree(buf);
971 return ret;
972}
973
974
975const struct file_operations diag_dbgfs_mhiinfo_ops = {
976 .read = diag_dbgfs_read_mhiinfo,
977};
978
979#endif
980static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf,
981 size_t count, loff_t *ppos)
982{
983 char *buf = NULL;
984 int ret = 0;
985 int i = 0;
986 unsigned int buf_size;
987 unsigned int bytes_remaining = 0;
988 unsigned int bytes_written = 0;
989 unsigned int bytes_in_buffer = 0;
990 struct diagfwd_bridge_info *info = NULL;
991
992 if (diag_dbgfs_bridgeinfo_index >= NUM_DIAG_USB_DEV) {
993 /* Done. Reset to prepare for future requests */
994 diag_dbgfs_bridgeinfo_index = 0;
995 return 0;
996 }
997
998 buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
999 if (ZERO_OR_NULL_PTR(buf)) {
1000 pr_err("diag: %s, Error allocating memory\n", __func__);
1001 return -ENOMEM;
1002 }
1003
1004 buf_size = ksize(buf);
1005 bytes_remaining = buf_size;
1006 for (i = diag_dbgfs_bridgeinfo_index; i < NUM_REMOTE_DEV; i++) {
1007 info = &bridge_info[i];
1008 if (!info->inited)
1009 continue;
1010 bytes_written = scnprintf(buf+bytes_in_buffer, bytes_remaining,
1011 "id: %d\n"
1012 "name: %s\n"
1013 "type: %d\n"
1014 "inited: %d\n"
1015 "ctxt: %d\n"
1016 "dev_ops: %pK\n"
1017 "dci_read_buf: %pK\n"
1018 "dci_read_ptr: %pK\n"
1019 "dci_read_len: %d\n\n",
1020 info->id,
1021 info->name,
1022 info->type,
1023 info->inited,
1024 info->ctxt,
1025 info->dev_ops,
1026 info->dci_read_buf,
1027 info->dci_read_ptr,
1028 info->dci_read_len);
1029 bytes_in_buffer += bytes_written;
1030
1031 /* Check if there is room to add another table entry */
1032 bytes_remaining = buf_size - bytes_in_buffer;
1033
1034 if (bytes_remaining < bytes_written)
1035 break;
1036 }
1037 diag_dbgfs_bridgeinfo_index = i+1;
1038 *ppos = 0;
1039 ret = simple_read_from_buffer(ubuf, count, ppos, buf, bytes_in_buffer);
1040
1041 kfree(buf);
1042 return ret;
1043}
1044
1045const struct file_operations diag_dbgfs_bridge_ops = {
1046 .read = diag_dbgfs_read_bridge,
1047};
1048
1049#endif
1050
1051const struct file_operations diag_dbgfs_status_ops = {
1052 .read = diag_dbgfs_read_status,
1053};
1054
Hardik Aryad6da1cb2017-11-23 20:40:55 +05301055#ifdef CONFIG_DIAG_USES_SMD
1056static const struct file_operations diag_dbgfs_smdinfo_ops = {
1057 .read = diag_dbgfs_read_smdinfo,
1058};
1059#endif
1060
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -07001061const struct file_operations diag_dbgfs_socketinfo_ops = {
1062 .read = diag_dbgfs_read_socketinfo,
1063};
1064
1065const struct file_operations diag_dbgfs_glinkinfo_ops = {
1066 .read = diag_dbgfs_read_glinkinfo,
1067};
1068
1069const struct file_operations diag_dbgfs_table_ops = {
1070 .read = diag_dbgfs_read_table,
1071};
1072
1073const struct file_operations diag_dbgfs_mempool_ops = {
1074 .read = diag_dbgfs_read_mempool,
1075};
1076
1077const struct file_operations diag_dbgfs_usbinfo_ops = {
1078 .read = diag_dbgfs_read_usbinfo,
1079};
1080
1081const struct file_operations diag_dbgfs_dcistats_ops = {
1082 .read = diag_dbgfs_read_dcistats,
1083};
1084
1085const struct file_operations diag_dbgfs_power_ops = {
1086 .read = diag_dbgfs_read_power,
1087};
1088
1089const struct file_operations diag_dbgfs_debug_ops = {
1090 .write = diag_dbgfs_write_debug
1091};
1092
1093int diag_debugfs_init(void)
1094{
1095 struct dentry *entry = NULL;
1096
1097 diag_dbgfs_dent = debugfs_create_dir("diag", 0);
1098 if (IS_ERR(diag_dbgfs_dent))
1099 return -ENOMEM;
1100
1101 entry = debugfs_create_file("status", 0444, diag_dbgfs_dent, 0,
1102 &diag_dbgfs_status_ops);
1103 if (!entry)
1104 goto err;
1105
Hardik Aryad6da1cb2017-11-23 20:40:55 +05301106#ifdef CONFIG_DIAG_USES_SMD
1107 entry = debugfs_create_file("smdinfo", 0444, diag_dbgfs_dent, NULL,
1108 &diag_dbgfs_smdinfo_ops);
1109 if (!entry)
1110 goto err;
1111#endif
1112
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -07001113 entry = debugfs_create_file("socketinfo", 0444, diag_dbgfs_dent, 0,
1114 &diag_dbgfs_socketinfo_ops);
1115 if (!entry)
1116 goto err;
1117
1118 entry = debugfs_create_file("glinkinfo", 0444, diag_dbgfs_dent, 0,
1119 &diag_dbgfs_glinkinfo_ops);
1120 if (!entry)
1121 goto err;
1122
1123 entry = debugfs_create_file("table", 0444, diag_dbgfs_dent, 0,
1124 &diag_dbgfs_table_ops);
1125 if (!entry)
1126 goto err;
1127
1128 entry = debugfs_create_file("mempool", 0444, diag_dbgfs_dent, 0,
1129 &diag_dbgfs_mempool_ops);
1130 if (!entry)
1131 goto err;
1132
1133 entry = debugfs_create_file("usbinfo", 0444, diag_dbgfs_dent, 0,
1134 &diag_dbgfs_usbinfo_ops);
1135 if (!entry)
1136 goto err;
1137
1138 entry = debugfs_create_file("dci_stats", 0444, diag_dbgfs_dent, 0,
1139 &diag_dbgfs_dcistats_ops);
1140 if (!entry)
1141 goto err;
1142
1143 entry = debugfs_create_file("power", 0444, diag_dbgfs_dent, 0,
1144 &diag_dbgfs_power_ops);
1145 if (!entry)
1146 goto err;
1147
1148 entry = debugfs_create_file("debug", 0444, diag_dbgfs_dent, 0,
1149 &diag_dbgfs_debug_ops);
1150 if (!entry)
1151 goto err;
1152
1153#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
1154 entry = debugfs_create_file("bridge", 0444, diag_dbgfs_dent, 0,
1155 &diag_dbgfs_bridge_ops);
1156 if (!entry)
1157 goto err;
1158#ifdef CONFIG_USB_QCOM_DIAG_BRIDGE
1159 entry = debugfs_create_file("hsicinfo", 0444, diag_dbgfs_dent, 0,
1160 &diag_dbgfs_hsicinfo_ops);
1161 if (!entry)
1162 goto err;
1163#endif
1164#ifdef CONFIG_MSM_MHI
1165 entry = debugfs_create_file("mhiinfo", 0444, diag_dbgfs_dent, 0,
1166 &diag_dbgfs_mhiinfo_ops);
1167 if (!entry)
1168 goto err;
1169#endif
1170#endif
1171 diag_dbgfs_table_index = 0;
1172 diag_dbgfs_mempool_index = 0;
1173 diag_dbgfs_usbinfo_index = 0;
Hardik Aryad6da1cb2017-11-23 20:40:55 +05301174 diag_dbgfs_smdinfo_index = 0;
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -07001175 diag_dbgfs_socketinfo_index = 0;
1176 diag_dbgfs_hsicinfo_index = 0;
1177 diag_dbgfs_bridgeinfo_index = 0;
1178 diag_dbgfs_mhiinfo_index = 0;
1179 diag_dbgfs_finished = 0;
1180 diag_dbgfs_dci_data_index = 0;
1181 diag_dbgfs_dci_finished = 0;
1182
1183 /* DCI related structures */
1184 dci_traffic = kzalloc(sizeof(struct diag_dci_data_info) *
1185 DIAG_DCI_DEBUG_CNT, GFP_KERNEL);
1186 if (ZERO_OR_NULL_PTR(dci_traffic))
1187 pr_warn("diag: could not allocate memory for dci debug info\n");
1188
1189 mutex_init(&dci_stat_mutex);
Sreelakshmi Gownipalli13e83672017-10-09 12:59:56 -07001190 mutex_init(&diag_dci_dbgfs_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -07001191 return 0;
1192err:
1193 kfree(dci_traffic);
1194 debugfs_remove_recursive(diag_dbgfs_dent);
1195 return -ENOMEM;
1196}
1197
1198void diag_debugfs_cleanup(void)
1199{
1200 debugfs_remove_recursive(diag_dbgfs_dent);
1201 diag_dbgfs_dent = NULL;
1202 kfree(dci_traffic);
1203 mutex_destroy(&dci_stat_mutex);
Sreelakshmi Gownipalli13e83672017-10-09 12:59:56 -07001204 mutex_destroy(&diag_dci_dbgfs_mutex);
Sreelakshmi Gownipallicb8893d2016-10-19 16:02:34 -07001205}
1206#else
1207int diag_debugfs_init(void) { return 0; }
1208void diag_debugfs_cleanup(void) { }
1209#endif