blob: 260092c5d49aeee12b490e8aceb15fd1a6259a66 [file] [log] [blame]
Felipe Balbi72246da2011-08-19 18:10:58 +03001/**
2 * debugfs.c - DesignWare USB3 DRD Controller DebugFS file
3 *
4 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
Felipe Balbi72246da2011-08-19 18:10:58 +03005 *
6 * Authors: Felipe Balbi <balbi@ti.com>,
7 * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8 *
Felipe Balbi5945f782013-06-30 14:15:11 +03009 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 of
11 * the License as published by the Free Software Foundation.
Felipe Balbi72246da2011-08-19 18:10:58 +030012 *
Felipe Balbi5945f782013-06-30 14:15:11 +030013 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
Felipe Balbi72246da2011-08-19 18:10:58 +030017 */
18
19#include <linux/kernel.h>
20#include <linux/slab.h>
21#include <linux/ptrace.h>
22#include <linux/types.h>
23#include <linux/spinlock.h>
24#include <linux/debugfs.h>
25#include <linux/seq_file.h>
26#include <linux/delay.h>
Felipe Balbi25b8ff62011-11-04 12:32:47 +020027#include <linux/uaccess.h>
Felipe Balbi72246da2011-08-19 18:10:58 +030028
Felipe Balbi080d9212012-01-02 18:38:30 +020029#include <linux/usb/ch9.h>
30
Felipe Balbi72246da2011-08-19 18:10:58 +030031#include "core.h"
32#include "gadget.h"
33#include "io.h"
Felipe Balbi8becf272011-11-04 12:40:05 +020034#include "debug.h"
Felipe Balbi72246da2011-08-19 18:10:58 +030035
Felipe Balbi72246da2011-08-19 18:10:58 +030036#define dump_register(nm) \
37{ \
38 .name = __stringify(nm), \
Felipe Balbi2eb88012016-04-12 16:53:39 +030039 .offset = DWC3_ ##nm, \
Felipe Balbi72246da2011-08-19 18:10:58 +030040}
41
Felipe Balbi2eb88012016-04-12 16:53:39 +030042#define dump_ep_register_set(n) \
43 { \
44 .name = "DEPCMDPAR2("__stringify(n)")", \
45 .offset = DWC3_DEP_BASE(n) + \
46 DWC3_DEPCMDPAR2, \
47 }, \
48 { \
49 .name = "DEPCMDPAR1("__stringify(n)")", \
50 .offset = DWC3_DEP_BASE(n) + \
51 DWC3_DEPCMDPAR1, \
52 }, \
53 { \
54 .name = "DEPCMDPAR0("__stringify(n)")", \
55 .offset = DWC3_DEP_BASE(n) + \
56 DWC3_DEPCMDPAR0, \
57 }, \
58 { \
59 .name = "DEPCMD("__stringify(n)")", \
60 .offset = DWC3_DEP_BASE(n) + \
61 DWC3_DEPCMD, \
62 }
63
64
Mayank Rana0c667b42017-02-09 11:56:51 -080065#define ep_event_rate(ev, c, p, dt) \
66 ((dt) ? ((c.ev - p.ev) * (MSEC_PER_SEC)) / (dt) : 0)
67
Felipe Balbi4ec0ddb2013-02-22 16:17:31 +020068static const struct debugfs_reg32 dwc3_regs[] = {
Felipe Balbi72246da2011-08-19 18:10:58 +030069 dump_register(GSBUSCFG0),
70 dump_register(GSBUSCFG1),
71 dump_register(GTXTHRCFG),
72 dump_register(GRXTHRCFG),
73 dump_register(GCTL),
74 dump_register(GEVTEN),
75 dump_register(GSTS),
William Wu475c8be2016-05-13 18:13:46 +080076 dump_register(GUCTL1),
Felipe Balbi72246da2011-08-19 18:10:58 +030077 dump_register(GSNPSID),
78 dump_register(GGPIO),
79 dump_register(GUID),
80 dump_register(GUCTL),
81 dump_register(GBUSERRADDR0),
82 dump_register(GBUSERRADDR1),
83 dump_register(GPRTBIMAP0),
84 dump_register(GPRTBIMAP1),
85 dump_register(GHWPARAMS0),
86 dump_register(GHWPARAMS1),
87 dump_register(GHWPARAMS2),
88 dump_register(GHWPARAMS3),
89 dump_register(GHWPARAMS4),
90 dump_register(GHWPARAMS5),
91 dump_register(GHWPARAMS6),
92 dump_register(GHWPARAMS7),
93 dump_register(GDBGFIFOSPACE),
94 dump_register(GDBGLTSSM),
95 dump_register(GPRTBIMAP_HS0),
96 dump_register(GPRTBIMAP_HS1),
97 dump_register(GPRTBIMAP_FS0),
98 dump_register(GPRTBIMAP_FS1),
99
100 dump_register(GUSB2PHYCFG(0)),
101 dump_register(GUSB2PHYCFG(1)),
102 dump_register(GUSB2PHYCFG(2)),
103 dump_register(GUSB2PHYCFG(3)),
104 dump_register(GUSB2PHYCFG(4)),
105 dump_register(GUSB2PHYCFG(5)),
106 dump_register(GUSB2PHYCFG(6)),
107 dump_register(GUSB2PHYCFG(7)),
108 dump_register(GUSB2PHYCFG(8)),
109 dump_register(GUSB2PHYCFG(9)),
110 dump_register(GUSB2PHYCFG(10)),
111 dump_register(GUSB2PHYCFG(11)),
112 dump_register(GUSB2PHYCFG(12)),
113 dump_register(GUSB2PHYCFG(13)),
114 dump_register(GUSB2PHYCFG(14)),
115 dump_register(GUSB2PHYCFG(15)),
116
117 dump_register(GUSB2I2CCTL(0)),
118 dump_register(GUSB2I2CCTL(1)),
119 dump_register(GUSB2I2CCTL(2)),
120 dump_register(GUSB2I2CCTL(3)),
121 dump_register(GUSB2I2CCTL(4)),
122 dump_register(GUSB2I2CCTL(5)),
123 dump_register(GUSB2I2CCTL(6)),
124 dump_register(GUSB2I2CCTL(7)),
125 dump_register(GUSB2I2CCTL(8)),
126 dump_register(GUSB2I2CCTL(9)),
127 dump_register(GUSB2I2CCTL(10)),
128 dump_register(GUSB2I2CCTL(11)),
129 dump_register(GUSB2I2CCTL(12)),
130 dump_register(GUSB2I2CCTL(13)),
131 dump_register(GUSB2I2CCTL(14)),
132 dump_register(GUSB2I2CCTL(15)),
133
134 dump_register(GUSB2PHYACC(0)),
135 dump_register(GUSB2PHYACC(1)),
136 dump_register(GUSB2PHYACC(2)),
137 dump_register(GUSB2PHYACC(3)),
138 dump_register(GUSB2PHYACC(4)),
139 dump_register(GUSB2PHYACC(5)),
140 dump_register(GUSB2PHYACC(6)),
141 dump_register(GUSB2PHYACC(7)),
142 dump_register(GUSB2PHYACC(8)),
143 dump_register(GUSB2PHYACC(9)),
144 dump_register(GUSB2PHYACC(10)),
145 dump_register(GUSB2PHYACC(11)),
146 dump_register(GUSB2PHYACC(12)),
147 dump_register(GUSB2PHYACC(13)),
148 dump_register(GUSB2PHYACC(14)),
149 dump_register(GUSB2PHYACC(15)),
150
151 dump_register(GUSB3PIPECTL(0)),
152 dump_register(GUSB3PIPECTL(1)),
153 dump_register(GUSB3PIPECTL(2)),
154 dump_register(GUSB3PIPECTL(3)),
155 dump_register(GUSB3PIPECTL(4)),
156 dump_register(GUSB3PIPECTL(5)),
157 dump_register(GUSB3PIPECTL(6)),
158 dump_register(GUSB3PIPECTL(7)),
159 dump_register(GUSB3PIPECTL(8)),
160 dump_register(GUSB3PIPECTL(9)),
161 dump_register(GUSB3PIPECTL(10)),
162 dump_register(GUSB3PIPECTL(11)),
163 dump_register(GUSB3PIPECTL(12)),
164 dump_register(GUSB3PIPECTL(13)),
165 dump_register(GUSB3PIPECTL(14)),
166 dump_register(GUSB3PIPECTL(15)),
167
168 dump_register(GTXFIFOSIZ(0)),
169 dump_register(GTXFIFOSIZ(1)),
170 dump_register(GTXFIFOSIZ(2)),
171 dump_register(GTXFIFOSIZ(3)),
172 dump_register(GTXFIFOSIZ(4)),
173 dump_register(GTXFIFOSIZ(5)),
174 dump_register(GTXFIFOSIZ(6)),
175 dump_register(GTXFIFOSIZ(7)),
176 dump_register(GTXFIFOSIZ(8)),
177 dump_register(GTXFIFOSIZ(9)),
178 dump_register(GTXFIFOSIZ(10)),
179 dump_register(GTXFIFOSIZ(11)),
180 dump_register(GTXFIFOSIZ(12)),
181 dump_register(GTXFIFOSIZ(13)),
182 dump_register(GTXFIFOSIZ(14)),
183 dump_register(GTXFIFOSIZ(15)),
184 dump_register(GTXFIFOSIZ(16)),
185 dump_register(GTXFIFOSIZ(17)),
186 dump_register(GTXFIFOSIZ(18)),
187 dump_register(GTXFIFOSIZ(19)),
188 dump_register(GTXFIFOSIZ(20)),
189 dump_register(GTXFIFOSIZ(21)),
190 dump_register(GTXFIFOSIZ(22)),
191 dump_register(GTXFIFOSIZ(23)),
192 dump_register(GTXFIFOSIZ(24)),
193 dump_register(GTXFIFOSIZ(25)),
194 dump_register(GTXFIFOSIZ(26)),
195 dump_register(GTXFIFOSIZ(27)),
196 dump_register(GTXFIFOSIZ(28)),
197 dump_register(GTXFIFOSIZ(29)),
198 dump_register(GTXFIFOSIZ(30)),
199 dump_register(GTXFIFOSIZ(31)),
200
201 dump_register(GRXFIFOSIZ(0)),
202 dump_register(GRXFIFOSIZ(1)),
203 dump_register(GRXFIFOSIZ(2)),
204 dump_register(GRXFIFOSIZ(3)),
205 dump_register(GRXFIFOSIZ(4)),
206 dump_register(GRXFIFOSIZ(5)),
207 dump_register(GRXFIFOSIZ(6)),
208 dump_register(GRXFIFOSIZ(7)),
209 dump_register(GRXFIFOSIZ(8)),
210 dump_register(GRXFIFOSIZ(9)),
211 dump_register(GRXFIFOSIZ(10)),
212 dump_register(GRXFIFOSIZ(11)),
213 dump_register(GRXFIFOSIZ(12)),
214 dump_register(GRXFIFOSIZ(13)),
215 dump_register(GRXFIFOSIZ(14)),
216 dump_register(GRXFIFOSIZ(15)),
217 dump_register(GRXFIFOSIZ(16)),
218 dump_register(GRXFIFOSIZ(17)),
219 dump_register(GRXFIFOSIZ(18)),
220 dump_register(GRXFIFOSIZ(19)),
221 dump_register(GRXFIFOSIZ(20)),
222 dump_register(GRXFIFOSIZ(21)),
223 dump_register(GRXFIFOSIZ(22)),
224 dump_register(GRXFIFOSIZ(23)),
225 dump_register(GRXFIFOSIZ(24)),
226 dump_register(GRXFIFOSIZ(25)),
227 dump_register(GRXFIFOSIZ(26)),
228 dump_register(GRXFIFOSIZ(27)),
229 dump_register(GRXFIFOSIZ(28)),
230 dump_register(GRXFIFOSIZ(29)),
231 dump_register(GRXFIFOSIZ(30)),
232 dump_register(GRXFIFOSIZ(31)),
233
234 dump_register(GEVNTADRLO(0)),
235 dump_register(GEVNTADRHI(0)),
236 dump_register(GEVNTSIZ(0)),
237 dump_register(GEVNTCOUNT(0)),
238
239 dump_register(GHWPARAMS8),
240 dump_register(DCFG),
241 dump_register(DCTL),
242 dump_register(DEVTEN),
243 dump_register(DSTS),
244 dump_register(DGCMDPAR),
245 dump_register(DGCMD),
246 dump_register(DALEPENA),
247
Felipe Balbi2eb88012016-04-12 16:53:39 +0300248 dump_ep_register_set(0),
249 dump_ep_register_set(1),
250 dump_ep_register_set(2),
251 dump_ep_register_set(3),
252 dump_ep_register_set(4),
253 dump_ep_register_set(5),
254 dump_ep_register_set(6),
255 dump_ep_register_set(7),
256 dump_ep_register_set(8),
257 dump_ep_register_set(9),
258 dump_ep_register_set(10),
259 dump_ep_register_set(11),
260 dump_ep_register_set(12),
261 dump_ep_register_set(13),
262 dump_ep_register_set(14),
263 dump_ep_register_set(15),
264 dump_ep_register_set(16),
265 dump_ep_register_set(17),
266 dump_ep_register_set(18),
267 dump_ep_register_set(19),
268 dump_ep_register_set(20),
269 dump_ep_register_set(21),
270 dump_ep_register_set(22),
271 dump_ep_register_set(23),
272 dump_ep_register_set(24),
273 dump_ep_register_set(25),
274 dump_ep_register_set(26),
275 dump_ep_register_set(27),
276 dump_ep_register_set(28),
277 dump_ep_register_set(29),
278 dump_ep_register_set(30),
279 dump_ep_register_set(31),
Felipe Balbi72246da2011-08-19 18:10:58 +0300280
281 dump_register(OCFG),
282 dump_register(OCTL),
George Cheriand4436c32013-03-14 16:05:24 +0530283 dump_register(OEVT),
Felipe Balbi72246da2011-08-19 18:10:58 +0300284 dump_register(OEVTEN),
285 dump_register(OSTS),
286};
287
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300288static int dwc3_mode_show(struct seq_file *s, void *unused)
289{
290 struct dwc3 *dwc = s->private;
291 unsigned long flags;
292 u32 reg;
293
294 spin_lock_irqsave(&dwc->lock, flags);
295 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
296 spin_unlock_irqrestore(&dwc->lock, flags);
297
298 switch (DWC3_GCTL_PRTCAP(reg)) {
299 case DWC3_GCTL_PRTCAP_HOST:
300 seq_printf(s, "host\n");
301 break;
302 case DWC3_GCTL_PRTCAP_DEVICE:
303 seq_printf(s, "device\n");
304 break;
305 case DWC3_GCTL_PRTCAP_OTG:
306 seq_printf(s, "OTG\n");
307 break;
308 default:
309 seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg));
310 }
311
312 return 0;
313}
314
315static int dwc3_mode_open(struct inode *inode, struct file *file)
316{
317 return single_open(file, dwc3_mode_show, inode->i_private);
318}
319
320static ssize_t dwc3_mode_write(struct file *file,
321 const char __user *ubuf, size_t count, loff_t *ppos)
322{
323 struct seq_file *s = file->private_data;
324 struct dwc3 *dwc = s->private;
325 unsigned long flags;
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100326 u32 mode = 0;
Sai Krishna Juturiafe7e122017-05-17 11:06:35 +0530327 char buf[32] = {};
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300328
329 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
330 return -EFAULT;
331
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300332 if (!strncmp(buf, "host", 4))
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100333 mode |= DWC3_GCTL_PRTCAP_HOST;
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300334
335 if (!strncmp(buf, "device", 6))
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100336 mode |= DWC3_GCTL_PRTCAP_DEVICE;
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300337
338 if (!strncmp(buf, "otg", 3))
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100339 mode |= DWC3_GCTL_PRTCAP_OTG;
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300340
Sebastian Andrzej Siewior3140e8c2011-10-31 22:25:40 +0100341 if (mode) {
342 spin_lock_irqsave(&dwc->lock, flags);
343 dwc3_set_mode(dwc, mode);
344 spin_unlock_irqrestore(&dwc->lock, flags);
345 }
Felipe Balbi0b9fe322011-10-17 08:50:39 +0300346 return count;
347}
348
349static const struct file_operations dwc3_mode_fops = {
350 .open = dwc3_mode_open,
351 .write = dwc3_mode_write,
352 .read = seq_read,
353 .llseek = seq_lseek,
354 .release = single_release,
355};
356
Felipe Balbi080d9212012-01-02 18:38:30 +0200357static int dwc3_testmode_show(struct seq_file *s, void *unused)
358{
359 struct dwc3 *dwc = s->private;
360 unsigned long flags;
361 u32 reg;
362
363 spin_lock_irqsave(&dwc->lock, flags);
364 reg = dwc3_readl(dwc->regs, DWC3_DCTL);
365 reg &= DWC3_DCTL_TSTCTRL_MASK;
366 reg >>= 1;
367 spin_unlock_irqrestore(&dwc->lock, flags);
368
369 switch (reg) {
370 case 0:
371 seq_printf(s, "no test\n");
372 break;
373 case TEST_J:
374 seq_printf(s, "test_j\n");
375 break;
376 case TEST_K:
377 seq_printf(s, "test_k\n");
378 break;
379 case TEST_SE0_NAK:
380 seq_printf(s, "test_se0_nak\n");
381 break;
382 case TEST_PACKET:
383 seq_printf(s, "test_packet\n");
384 break;
385 case TEST_FORCE_EN:
386 seq_printf(s, "test_force_enable\n");
387 break;
388 default:
389 seq_printf(s, "UNKNOWN %d\n", reg);
390 }
391
392 return 0;
393}
394
395static int dwc3_testmode_open(struct inode *inode, struct file *file)
396{
397 return single_open(file, dwc3_testmode_show, inode->i_private);
398}
399
400static ssize_t dwc3_testmode_write(struct file *file,
401 const char __user *ubuf, size_t count, loff_t *ppos)
402{
403 struct seq_file *s = file->private_data;
404 struct dwc3 *dwc = s->private;
405 unsigned long flags;
406 u32 testmode = 0;
Sai Krishna Juturiafe7e122017-05-17 11:06:35 +0530407 char buf[32] = {};
Felipe Balbi080d9212012-01-02 18:38:30 +0200408
409 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
410 return -EFAULT;
411
412 if (!strncmp(buf, "test_j", 6))
413 testmode = TEST_J;
414 else if (!strncmp(buf, "test_k", 6))
415 testmode = TEST_K;
Gerard Cauvy09072542012-02-10 12:14:53 +0200416 else if (!strncmp(buf, "test_se0_nak", 12))
Felipe Balbi080d9212012-01-02 18:38:30 +0200417 testmode = TEST_SE0_NAK;
Gerard Cauvy09072542012-02-10 12:14:53 +0200418 else if (!strncmp(buf, "test_packet", 11))
Felipe Balbi080d9212012-01-02 18:38:30 +0200419 testmode = TEST_PACKET;
Gerard Cauvy09072542012-02-10 12:14:53 +0200420 else if (!strncmp(buf, "test_force_enable", 17))
Felipe Balbi080d9212012-01-02 18:38:30 +0200421 testmode = TEST_FORCE_EN;
422 else
423 testmode = 0;
424
425 spin_lock_irqsave(&dwc->lock, flags);
426 dwc3_gadget_set_test_mode(dwc, testmode);
427 spin_unlock_irqrestore(&dwc->lock, flags);
428
429 return count;
430}
431
432static const struct file_operations dwc3_testmode_fops = {
433 .open = dwc3_testmode_open,
434 .write = dwc3_testmode_write,
435 .read = seq_read,
436 .llseek = seq_lseek,
437 .release = single_release,
438};
439
Felipe Balbi138801a2012-01-02 19:25:16 +0200440static int dwc3_link_state_show(struct seq_file *s, void *unused)
441{
442 struct dwc3 *dwc = s->private;
443 unsigned long flags;
444 enum dwc3_link_state state;
445 u32 reg;
446
447 spin_lock_irqsave(&dwc->lock, flags);
448 reg = dwc3_readl(dwc->regs, DWC3_DSTS);
449 state = DWC3_DSTS_USBLNKST(reg);
450 spin_unlock_irqrestore(&dwc->lock, flags);
451
452 switch (state) {
453 case DWC3_LINK_STATE_U0:
454 seq_printf(s, "U0\n");
455 break;
456 case DWC3_LINK_STATE_U1:
457 seq_printf(s, "U1\n");
458 break;
459 case DWC3_LINK_STATE_U2:
460 seq_printf(s, "U2\n");
461 break;
462 case DWC3_LINK_STATE_U3:
463 seq_printf(s, "U3\n");
464 break;
465 case DWC3_LINK_STATE_SS_DIS:
466 seq_printf(s, "SS.Disabled\n");
467 break;
468 case DWC3_LINK_STATE_RX_DET:
469 seq_printf(s, "Rx.Detect\n");
470 break;
471 case DWC3_LINK_STATE_SS_INACT:
472 seq_printf(s, "SS.Inactive\n");
473 break;
474 case DWC3_LINK_STATE_POLL:
475 seq_printf(s, "Poll\n");
476 break;
477 case DWC3_LINK_STATE_RECOV:
478 seq_printf(s, "Recovery\n");
479 break;
480 case DWC3_LINK_STATE_HRESET:
481 seq_printf(s, "HRESET\n");
482 break;
483 case DWC3_LINK_STATE_CMPLY:
484 seq_printf(s, "Compliance\n");
485 break;
486 case DWC3_LINK_STATE_LPBK:
487 seq_printf(s, "Loopback\n");
488 break;
Felipe Balbi6b2a0eb2013-02-22 14:28:54 +0200489 case DWC3_LINK_STATE_RESET:
490 seq_printf(s, "Reset\n");
491 break;
492 case DWC3_LINK_STATE_RESUME:
493 seq_printf(s, "Resume\n");
494 break;
Felipe Balbi138801a2012-01-02 19:25:16 +0200495 default:
Felipe Balbi5b9ec332013-02-22 14:29:39 +0200496 seq_printf(s, "UNKNOWN %d\n", state);
Felipe Balbi138801a2012-01-02 19:25:16 +0200497 }
498
499 return 0;
500}
501
502static int dwc3_link_state_open(struct inode *inode, struct file *file)
503{
504 return single_open(file, dwc3_link_state_show, inode->i_private);
505}
506
507static ssize_t dwc3_link_state_write(struct file *file,
508 const char __user *ubuf, size_t count, loff_t *ppos)
509{
510 struct seq_file *s = file->private_data;
511 struct dwc3 *dwc = s->private;
512 unsigned long flags;
513 enum dwc3_link_state state = 0;
Sai Krishna Juturiafe7e122017-05-17 11:06:35 +0530514 char buf[32] = {};
Felipe Balbi138801a2012-01-02 19:25:16 +0200515
516 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
517 return -EFAULT;
518
519 if (!strncmp(buf, "SS.Disabled", 11))
520 state = DWC3_LINK_STATE_SS_DIS;
521 else if (!strncmp(buf, "Rx.Detect", 9))
522 state = DWC3_LINK_STATE_RX_DET;
523 else if (!strncmp(buf, "SS.Inactive", 11))
524 state = DWC3_LINK_STATE_SS_INACT;
525 else if (!strncmp(buf, "Recovery", 8))
526 state = DWC3_LINK_STATE_RECOV;
527 else if (!strncmp(buf, "Compliance", 10))
528 state = DWC3_LINK_STATE_CMPLY;
529 else if (!strncmp(buf, "Loopback", 8))
530 state = DWC3_LINK_STATE_LPBK;
531 else
532 return -EINVAL;
533
534 spin_lock_irqsave(&dwc->lock, flags);
535 dwc3_gadget_set_link_state(dwc, state);
536 spin_unlock_irqrestore(&dwc->lock, flags);
537
538 return count;
539}
540
541static const struct file_operations dwc3_link_state_fops = {
542 .open = dwc3_link_state_open,
543 .write = dwc3_link_state_write,
544 .read = seq_read,
545 .llseek = seq_lseek,
546 .release = single_release,
547};
548
Felipe Balbi818ec3a2016-04-14 14:53:44 +0300549struct dwc3_ep_file_map {
550 char name[25];
551 int (*show)(struct seq_file *s, void *unused);
552};
Felipe Balbi72246da2011-08-19 18:10:58 +0300553
Felipe Balbi818ec3a2016-04-14 14:53:44 +0300554static int dwc3_tx_fifo_queue_show(struct seq_file *s, void *unused)
555{
556 struct dwc3_ep *dep = s->private;
557 struct dwc3 *dwc = dep->dwc;
558 unsigned long flags;
559 u32 val;
560
561 spin_lock_irqsave(&dwc->lock, flags);
562 val = dwc3_core_fifo_space(dep, DWC3_TXFIFOQ);
563 seq_printf(s, "%u\n", val);
564 spin_unlock_irqrestore(&dwc->lock, flags);
565
566 return 0;
567}
568
569static int dwc3_rx_fifo_queue_show(struct seq_file *s, void *unused)
570{
571 struct dwc3_ep *dep = s->private;
572 struct dwc3 *dwc = dep->dwc;
573 unsigned long flags;
574 u32 val;
575
576 spin_lock_irqsave(&dwc->lock, flags);
577 val = dwc3_core_fifo_space(dep, DWC3_RXFIFOQ);
578 seq_printf(s, "%u\n", val);
579 spin_unlock_irqrestore(&dwc->lock, flags);
580
581 return 0;
582}
583
584static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused)
585{
586 struct dwc3_ep *dep = s->private;
587 struct dwc3 *dwc = dep->dwc;
588 unsigned long flags;
589 u32 val;
590
591 spin_lock_irqsave(&dwc->lock, flags);
592 val = dwc3_core_fifo_space(dep, DWC3_TXREQQ);
593 seq_printf(s, "%u\n", val);
594 spin_unlock_irqrestore(&dwc->lock, flags);
595
596 return 0;
597}
598
599static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused)
600{
601 struct dwc3_ep *dep = s->private;
602 struct dwc3 *dwc = dep->dwc;
603 unsigned long flags;
604 u32 val;
605
606 spin_lock_irqsave(&dwc->lock, flags);
607 val = dwc3_core_fifo_space(dep, DWC3_RXREQQ);
608 seq_printf(s, "%u\n", val);
609 spin_unlock_irqrestore(&dwc->lock, flags);
610
611 return 0;
612}
613
614static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused)
615{
616 struct dwc3_ep *dep = s->private;
617 struct dwc3 *dwc = dep->dwc;
618 unsigned long flags;
619 u32 val;
620
621 spin_lock_irqsave(&dwc->lock, flags);
622 val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ);
623 seq_printf(s, "%u\n", val);
624 spin_unlock_irqrestore(&dwc->lock, flags);
625
626 return 0;
627}
628
629static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused)
630{
631 struct dwc3_ep *dep = s->private;
632 struct dwc3 *dwc = dep->dwc;
633 unsigned long flags;
634 u32 val;
635
636 spin_lock_irqsave(&dwc->lock, flags);
637 val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ);
638 seq_printf(s, "%u\n", val);
639 spin_unlock_irqrestore(&dwc->lock, flags);
640
641 return 0;
642}
643
644static int dwc3_event_queue_show(struct seq_file *s, void *unused)
645{
646 struct dwc3_ep *dep = s->private;
647 struct dwc3 *dwc = dep->dwc;
648 unsigned long flags;
649 u32 val;
650
651 spin_lock_irqsave(&dwc->lock, flags);
652 val = dwc3_core_fifo_space(dep, DWC3_EVENTQ);
653 seq_printf(s, "%u\n", val);
654 spin_unlock_irqrestore(&dwc->lock, flags);
655
656 return 0;
657}
658
659static int dwc3_ep_transfer_type_show(struct seq_file *s, void *unused)
660{
661 struct dwc3_ep *dep = s->private;
662 struct dwc3 *dwc = dep->dwc;
663 unsigned long flags;
664
665 spin_lock_irqsave(&dwc->lock, flags);
666 if (!(dep->flags & DWC3_EP_ENABLED) ||
667 !dep->endpoint.desc) {
668 seq_printf(s, "--\n");
669 goto out;
Felipe Balbi72246da2011-08-19 18:10:58 +0300670 }
671
Felipe Balbi818ec3a2016-04-14 14:53:44 +0300672 switch (usb_endpoint_type(dep->endpoint.desc)) {
673 case USB_ENDPOINT_XFER_CONTROL:
674 seq_printf(s, "control\n");
675 break;
676 case USB_ENDPOINT_XFER_ISOC:
677 seq_printf(s, "isochronous\n");
678 break;
679 case USB_ENDPOINT_XFER_BULK:
680 seq_printf(s, "bulk\n");
681 break;
682 case USB_ENDPOINT_XFER_INT:
683 seq_printf(s, "interrupt\n");
684 break;
685 default:
686 seq_printf(s, "--\n");
687 }
688
689out:
690 spin_unlock_irqrestore(&dwc->lock, flags);
691
692 return 0;
693}
694
695static inline const char *dwc3_trb_type_string(struct dwc3_trb *trb)
696{
697 switch (DWC3_TRBCTL_TYPE(trb->ctrl)) {
698 case DWC3_TRBCTL_NORMAL:
699 return "normal";
700 case DWC3_TRBCTL_CONTROL_SETUP:
701 return "control-setup";
702 case DWC3_TRBCTL_CONTROL_STATUS2:
703 return "control-status2";
704 case DWC3_TRBCTL_CONTROL_STATUS3:
705 return "control-status3";
706 case DWC3_TRBCTL_CONTROL_DATA:
707 return "control-data";
708 case DWC3_TRBCTL_ISOCHRONOUS_FIRST:
709 return "isoc-first";
710 case DWC3_TRBCTL_ISOCHRONOUS:
711 return "isoc";
712 case DWC3_TRBCTL_LINK_TRB:
713 return "link";
714 default:
715 return "UNKNOWN";
716 }
717}
718
719static int dwc3_ep_trb_ring_show(struct seq_file *s, void *unused)
720{
721 struct dwc3_ep *dep = s->private;
722 struct dwc3 *dwc = dep->dwc;
723 unsigned long flags;
724 int i;
725
726 spin_lock_irqsave(&dwc->lock, flags);
727 if (dep->number <= 1) {
728 seq_printf(s, "--\n");
729 goto out;
730 }
731
732 seq_printf(s, "enqueue pointer %d\n", dep->trb_enqueue);
733 seq_printf(s, "dequeue pointer %d\n", dep->trb_dequeue);
734 seq_printf(s, "\n--------------------------------------------------\n\n");
735 seq_printf(s, "buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo\n");
736
737 for (i = 0; i < DWC3_TRB_NUM; i++) {
738 struct dwc3_trb *trb = &dep->trb_pool[i];
739
740 seq_printf(s, "%08x%08x,%d,%s,%d,%d,%d,%d,%d,%d\n",
741 trb->bph, trb->bpl, trb->size,
742 dwc3_trb_type_string(trb),
743 !!(trb->ctrl & DWC3_TRB_CTRL_IOC),
744 !!(trb->ctrl & DWC3_TRB_CTRL_ISP_IMI),
745 !!(trb->ctrl & DWC3_TRB_CTRL_CSP),
746 !!(trb->ctrl & DWC3_TRB_CTRL_CHN),
747 !!(trb->ctrl & DWC3_TRB_CTRL_LST),
748 !!(trb->ctrl & DWC3_TRB_CTRL_HWO));
749 }
750
751out:
752 spin_unlock_irqrestore(&dwc->lock, flags);
753
754 return 0;
755}
756
757static struct dwc3_ep_file_map map[] = {
758 { "tx_fifo_queue", dwc3_tx_fifo_queue_show, },
759 { "rx_fifo_queue", dwc3_rx_fifo_queue_show, },
760 { "tx_request_queue", dwc3_tx_request_queue_show, },
761 { "rx_request_queue", dwc3_rx_request_queue_show, },
762 { "rx_info_queue", dwc3_rx_info_queue_show, },
763 { "descriptor_fetch_queue", dwc3_descriptor_fetch_queue_show, },
764 { "event_queue", dwc3_event_queue_show, },
765 { "transfer_type", dwc3_ep_transfer_type_show, },
766 { "trb_ring", dwc3_ep_trb_ring_show, },
767};
768
769static int dwc3_endpoint_open(struct inode *inode, struct file *file)
770{
771 const char *file_name = file_dentry(file)->d_iname;
772 struct dwc3_ep_file_map *f_map;
773 int i;
774
775 for (i = 0; i < ARRAY_SIZE(map); i++) {
776 f_map = &map[i];
777
778 if (strcmp(f_map->name, file_name) == 0)
779 break;
780 }
781
782 return single_open(file, f_map->show, inode->i_private);
783}
784
785static const struct file_operations dwc3_endpoint_fops = {
786 .open = dwc3_endpoint_open,
787 .read = seq_read,
788 .llseek = seq_lseek,
789 .release = single_release,
790};
791
792static void dwc3_debugfs_create_endpoint_file(struct dwc3_ep *dep,
793 struct dentry *parent, int type)
794{
795 struct dentry *file;
796 struct dwc3_ep_file_map *ep_file = &map[type];
797
798 file = debugfs_create_file(ep_file->name, S_IRUGO, parent, dep,
799 &dwc3_endpoint_fops);
800}
801
802static void dwc3_debugfs_create_endpoint_files(struct dwc3_ep *dep,
803 struct dentry *parent)
804{
805 int i;
806
807 for (i = 0; i < ARRAY_SIZE(map); i++)
808 dwc3_debugfs_create_endpoint_file(dep, parent, i);
809}
810
811static void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep,
812 struct dentry *parent)
813{
814 struct dentry *dir;
815
816 dir = debugfs_create_dir(dep->name, parent);
817 if (IS_ERR_OR_NULL(dir))
818 return;
819
820 dwc3_debugfs_create_endpoint_files(dep, dir);
821}
822
823static void dwc3_debugfs_create_endpoint_dirs(struct dwc3 *dwc,
824 struct dentry *parent)
825{
826 int i;
827
828 for (i = 0; i < dwc->num_in_eps; i++) {
829 u8 epnum = (i << 1) | 1;
830 struct dwc3_ep *dep = dwc->eps[epnum];
831
832 if (!dep)
833 continue;
834
835 dwc3_debugfs_create_endpoint_dir(dep, parent);
836 }
837
838 for (i = 0; i < dwc->num_out_eps; i++) {
839 u8 epnum = (i << 1);
840 struct dwc3_ep *dep = dwc->eps[epnum];
841
842 if (!dep)
843 continue;
844
845 dwc3_debugfs_create_endpoint_dir(dep, parent);
846 }
847}
848
Mayank Rana0c667b42017-02-09 11:56:51 -0800849static ssize_t dwc3_store_int_events(struct file *file,
850 const char __user *ubuf, size_t count, loff_t *ppos)
851{
852 int i, ret;
853 unsigned long flags;
854 struct seq_file *s = file->private_data;
855 struct dwc3 *dwc = s->private;
856 struct dwc3_ep *dep;
857 struct timespec ts;
858 u8 clear_stats;
859
860 if (ubuf == NULL) {
861 pr_err("[%s] EINVAL\n", __func__);
862 ret = -EINVAL;
863 return ret;
864 }
865
866 ret = kstrtou8_from_user(ubuf, count, 0, &clear_stats);
867 if (ret < 0) {
868 pr_err("can't get enter value.\n");
869 return ret;
870 }
871
872 if (clear_stats != 0) {
873 pr_err("Wrong value. To clear stats, enter value as 0.\n");
874 ret = -EINVAL;
875 return ret;
876 }
877
878 pr_debug("%s(): clearing debug interrupt buffers\n", __func__);
879 spin_lock_irqsave(&dwc->lock, flags);
880 ts = current_kernel_time();
881 for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
882 dep = dwc->eps[i];
883 memset(&dep->dbg_ep_events, 0, sizeof(dep->dbg_ep_events));
884 memset(&dep->dbg_ep_events_diff, 0, sizeof(dep->dbg_ep_events));
885 dep->dbg_ep_events_ts = ts;
886 }
887 memset(&dwc->dbg_gadget_events, 0, sizeof(dwc->dbg_gadget_events));
888 spin_unlock_irqrestore(&dwc->lock, flags);
889 return count;
890}
891
892static int dwc3_gadget_int_events_show(struct seq_file *s, void *unused)
893{
894 unsigned long flags;
895 struct dwc3 *dwc = s->private;
896 struct dwc3_gadget_events *dbg_gadget_events;
897 struct dwc3_ep *dep;
898 int i;
899 struct timespec ts_delta;
900 struct timespec ts_current;
901 u32 ts_delta_ms;
902
903 spin_lock_irqsave(&dwc->lock, flags);
904 dbg_gadget_events = &dwc->dbg_gadget_events;
905
906 for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
907 dep = dwc->eps[i];
908
909 if (dep == NULL || !(dep->flags & DWC3_EP_ENABLED))
910 continue;
911
912 ts_current = current_kernel_time();
913 ts_delta = timespec_sub(ts_current, dep->dbg_ep_events_ts);
914 ts_delta_ms = ts_delta.tv_nsec / NSEC_PER_MSEC +
915 ts_delta.tv_sec * MSEC_PER_SEC;
916
917 seq_printf(s, "\n\n===== dbg_ep_events for EP(%d) %s =====\n",
918 i, dep->name);
919 seq_printf(s, "xfercomplete:%u @ %luHz\n",
920 dep->dbg_ep_events.xfercomplete,
921 ep_event_rate(xfercomplete, dep->dbg_ep_events,
922 dep->dbg_ep_events_diff, ts_delta_ms));
923 seq_printf(s, "xfernotready:%u @ %luHz\n",
924 dep->dbg_ep_events.xfernotready,
925 ep_event_rate(xfernotready, dep->dbg_ep_events,
926 dep->dbg_ep_events_diff, ts_delta_ms));
927 seq_printf(s, "control_data:%u @ %luHz\n",
928 dep->dbg_ep_events.control_data,
929 ep_event_rate(control_data, dep->dbg_ep_events,
930 dep->dbg_ep_events_diff, ts_delta_ms));
931 seq_printf(s, "control_status:%u @ %luHz\n",
932 dep->dbg_ep_events.control_status,
933 ep_event_rate(control_status, dep->dbg_ep_events,
934 dep->dbg_ep_events_diff, ts_delta_ms));
935 seq_printf(s, "xferinprogress:%u @ %luHz\n",
936 dep->dbg_ep_events.xferinprogress,
937 ep_event_rate(xferinprogress, dep->dbg_ep_events,
938 dep->dbg_ep_events_diff, ts_delta_ms));
939 seq_printf(s, "rxtxfifoevent:%u @ %luHz\n",
940 dep->dbg_ep_events.rxtxfifoevent,
941 ep_event_rate(rxtxfifoevent, dep->dbg_ep_events,
942 dep->dbg_ep_events_diff, ts_delta_ms));
943 seq_printf(s, "streamevent:%u @ %luHz\n",
944 dep->dbg_ep_events.streamevent,
945 ep_event_rate(streamevent, dep->dbg_ep_events,
946 dep->dbg_ep_events_diff, ts_delta_ms));
947 seq_printf(s, "epcmdcomplt:%u @ %luHz\n",
948 dep->dbg_ep_events.epcmdcomplete,
949 ep_event_rate(epcmdcomplete, dep->dbg_ep_events,
950 dep->dbg_ep_events_diff, ts_delta_ms));
951 seq_printf(s, "unknown:%u @ %luHz\n",
952 dep->dbg_ep_events.unknown_event,
953 ep_event_rate(unknown_event, dep->dbg_ep_events,
954 dep->dbg_ep_events_diff, ts_delta_ms));
955 seq_printf(s, "total:%u @ %luHz\n",
956 dep->dbg_ep_events.total,
957 ep_event_rate(total, dep->dbg_ep_events,
958 dep->dbg_ep_events_diff, ts_delta_ms));
959
960 dep->dbg_ep_events_ts = ts_current;
961 dep->dbg_ep_events_diff = dep->dbg_ep_events;
962 }
963
964 seq_puts(s, "\n=== dbg_gadget events ==\n");
965 seq_printf(s, "disconnect:%u\n reset:%u\n",
966 dbg_gadget_events->disconnect, dbg_gadget_events->reset);
967 seq_printf(s, "connect:%u\n wakeup:%u\n",
968 dbg_gadget_events->connect, dbg_gadget_events->wakeup);
969 seq_printf(s, "link_status_change:%u\n eopf:%u\n",
970 dbg_gadget_events->link_status_change, dbg_gadget_events->eopf);
971 seq_printf(s, "sof:%u\n suspend:%u\n",
972 dbg_gadget_events->sof, dbg_gadget_events->suspend);
973 seq_printf(s, "erratic_error:%u\n overflow:%u\n",
974 dbg_gadget_events->erratic_error,
975 dbg_gadget_events->overflow);
976 seq_printf(s, "vendor_dev_test_lmp:%u\n cmdcmplt:%u\n",
977 dbg_gadget_events->vendor_dev_test_lmp,
978 dbg_gadget_events->cmdcmplt);
979 seq_printf(s, "unknown_event:%u\n", dbg_gadget_events->unknown_event);
980
Mayank Rana7020a382017-02-09 12:32:58 -0800981 seq_printf(s, "\n\t== Last %d interrupts stats ==\t\n", MAX_INTR_STATS);
982 seq_puts(s, "@ time (us):\t");
983 for (i = 0; i < MAX_INTR_STATS; i++)
984 seq_printf(s, "%lld\t", ktime_to_us(dwc->irq_start_time[i]));
985 seq_puts(s, "\nhard irq time (us):\t");
986 for (i = 0; i < MAX_INTR_STATS; i++)
987 seq_printf(s, "%d\t", dwc->irq_completion_time[i]);
988 seq_puts(s, "\nevents count:\t\t");
989 for (i = 0; i < MAX_INTR_STATS; i++)
990 seq_printf(s, "%d\t", dwc->irq_event_count[i]);
991 seq_puts(s, "\nbh handled count:\t");
992 for (i = 0; i < MAX_INTR_STATS; i++)
993 seq_printf(s, "%d\t", dwc->bh_handled_evt_cnt[i]);
994 seq_puts(s, "\nirq thread time (us):\t");
995 for (i = 0; i < MAX_INTR_STATS; i++)
996 seq_printf(s, "%d\t", dwc->bh_completion_time[i]);
997 seq_putc(s, '\n');
998
Hemant Kumare4f27812017-01-27 18:31:22 -0800999 seq_printf(s, "t_pwr evt irq : %lld\n",
1000 ktime_to_us(dwc->t_pwr_evt_irq));
1001
1002 seq_printf(s, "l1_remote_wakeup_cnt : %lu\n",
1003 dwc->l1_remote_wakeup_cnt);
1004
Mayank Rana0c667b42017-02-09 11:56:51 -08001005 spin_unlock_irqrestore(&dwc->lock, flags);
1006 return 0;
1007}
1008
1009static int dwc3_gadget_events_open(struct inode *inode, struct file *f)
1010{
1011 return single_open(f, dwc3_gadget_int_events_show, inode->i_private);
1012}
1013
1014const struct file_operations dwc3_gadget_dbg_events_fops = {
1015 .open = dwc3_gadget_events_open,
1016 .read = seq_read,
1017 .write = dwc3_store_int_events,
1018 .llseek = seq_lseek,
1019 .release = single_release,
1020};
1021
Mayank Ranaa99689a2016-08-10 17:39:47 -07001022int dwc3_debugfs_init(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +03001023{
1024 struct dentry *root;
Du, Changbin4e9f3112016-04-12 19:10:18 +08001025 struct dentry *file;
Mayank Ranaa99689a2016-08-10 17:39:47 -07001026 int ret;
Felipe Balbi72246da2011-08-19 18:10:58 +03001027
1028 root = debugfs_create_dir(dev_name(dwc->dev), NULL);
Du, Changbin4e9f3112016-04-12 19:10:18 +08001029 if (IS_ERR_OR_NULL(root)) {
1030 if (!root)
1031 dev_err(dwc->dev, "Can't create debugfs root\n");
Mayank Ranaa99689a2016-08-10 17:39:47 -07001032 ret = -ENOMEM;
1033 goto err0;
Felipe Balbi72246da2011-08-19 18:10:58 +03001034 }
Felipe Balbi72246da2011-08-19 18:10:58 +03001035 dwc->root = root;
1036
Felipe Balbid7668022013-01-18 10:21:34 +02001037 dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL);
1038 if (!dwc->regset) {
Mayank Ranaa99689a2016-08-10 17:39:47 -07001039 ret = -ENOMEM;
1040 goto err1;
Felipe Balbid7668022013-01-18 10:21:34 +02001041 }
1042
1043 dwc->regset->regs = dwc3_regs;
1044 dwc->regset->nregs = ARRAY_SIZE(dwc3_regs);
Felipe Balbi2eb88012016-04-12 16:53:39 +03001045 dwc->regset->base = dwc->regs - DWC3_GLOBALS_REGS_START;
Felipe Balbid7668022013-01-18 10:21:34 +02001046
1047 file = debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset);
Du, Changbin4e9f3112016-04-12 19:10:18 +08001048 if (!file)
1049 dev_dbg(dwc->dev, "Can't create debugfs regdump\n");
Felipe Balbi0b9fe322011-10-17 08:50:39 +03001050
Felipe Balbidbfff052013-02-22 16:24:49 +02001051 if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) {
1052 file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root,
1053 dwc, &dwc3_mode_fops);
Du, Changbin4e9f3112016-04-12 19:10:18 +08001054 if (!file)
1055 dev_dbg(dwc->dev, "Can't create debugfs mode\n");
Felipe Balbi0b9fe322011-10-17 08:50:39 +03001056 }
1057
Felipe Balbidbfff052013-02-22 16:24:49 +02001058 if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) ||
1059 IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
1060 file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root,
1061 dwc, &dwc3_testmode_fops);
Du, Changbin4e9f3112016-04-12 19:10:18 +08001062 if (!file)
1063 dev_dbg(dwc->dev, "Can't create debugfs testmode\n");
Felipe Balbi080d9212012-01-02 18:38:30 +02001064
Du, Changbin4e9f3112016-04-12 19:10:18 +08001065 file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR,
1066 root, dwc, &dwc3_link_state_fops);
1067 if (!file)
1068 dev_dbg(dwc->dev, "Can't create debugfs link_state\n");
Felipe Balbi818ec3a2016-04-14 14:53:44 +03001069
1070 dwc3_debugfs_create_endpoint_dirs(dwc, root);
Mayank Rana0c667b42017-02-09 11:56:51 -08001071
1072 file = debugfs_create_file("int_events", 0644, root, dwc,
1073 &dwc3_gadget_dbg_events_fops);
1074 if (!file) {
1075 ret = -ENOMEM;
1076 goto err1;
1077 }
Felipe Balbi138801a2012-01-02 19:25:16 +02001078 }
Mayank Ranaa99689a2016-08-10 17:39:47 -07001079
1080 return 0;
1081
1082err1:
1083 debugfs_remove_recursive(root);
1084err0:
1085 return ret;
Felipe Balbi72246da2011-08-19 18:10:58 +03001086}
1087
Bill Pembertonfb4e98a2012-11-19 13:26:20 -05001088void dwc3_debugfs_exit(struct dwc3 *dwc)
Felipe Balbi72246da2011-08-19 18:10:58 +03001089{
1090 debugfs_remove_recursive(dwc->root);
Du, Changbine6bdf812016-04-12 16:24:34 +08001091 kfree(dwc->regset);
Felipe Balbi72246da2011-08-19 18:10:58 +03001092}