UPSTREAM: usb: dwc3: debugfs: fix regdump offset
[cascardo/linux.git] / drivers / usb / dwc3 / debugfs.c
1 /**
2  * debugfs.c - DesignWare USB3 DRD Controller DebugFS file
3  *
4  * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
5  *
6  * Authors: Felipe Balbi <balbi@ti.com>,
7  *          Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions, and the following disclaimer,
14  *    without modification.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. The names of the above-listed copyright holders may not be used
19  *    to endorse or promote products derived from this software without
20  *    specific prior written permission.
21  *
22  * ALTERNATIVELY, this software may be distributed under the terms of the
23  * GNU General Public License ("GPL") version 2, as published by the Free
24  * Software Foundation.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
27  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
28  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
30  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  */
38
39 #include <linux/kernel.h>
40 #include <linux/slab.h>
41 #include <linux/ptrace.h>
42 #include <linux/types.h>
43 #include <linux/spinlock.h>
44 #include <linux/debugfs.h>
45 #include <linux/seq_file.h>
46 #include <linux/delay.h>
47 #include <linux/uaccess.h>
48
49 #include <linux/usb/ch9.h>
50
51 #include "core.h"
52 #include "gadget.h"
53 #include "io.h"
54 #include "debug.h"
55
56 #define dump_register(nm)                               \
57 {                                                       \
58         .name   = __stringify(nm),                      \
59         .offset = DWC3_ ##nm - DWC3_GLOBALS_REGS_START, \
60 }
61
62 static const struct debugfs_reg32 dwc3_regs[] = {
63         dump_register(GSBUSCFG0),
64         dump_register(GSBUSCFG1),
65         dump_register(GTXTHRCFG),
66         dump_register(GRXTHRCFG),
67         dump_register(GCTL),
68         dump_register(GEVTEN),
69         dump_register(GSTS),
70         dump_register(GSNPSID),
71         dump_register(GGPIO),
72         dump_register(GUID),
73         dump_register(GUCTL),
74         dump_register(GBUSERRADDR0),
75         dump_register(GBUSERRADDR1),
76         dump_register(GPRTBIMAP0),
77         dump_register(GPRTBIMAP1),
78         dump_register(GHWPARAMS0),
79         dump_register(GHWPARAMS1),
80         dump_register(GHWPARAMS2),
81         dump_register(GHWPARAMS3),
82         dump_register(GHWPARAMS4),
83         dump_register(GHWPARAMS5),
84         dump_register(GHWPARAMS6),
85         dump_register(GHWPARAMS7),
86         dump_register(GDBGFIFOSPACE),
87         dump_register(GDBGLTSSM),
88         dump_register(GPRTBIMAP_HS0),
89         dump_register(GPRTBIMAP_HS1),
90         dump_register(GPRTBIMAP_FS0),
91         dump_register(GPRTBIMAP_FS1),
92
93         dump_register(GUSB2PHYCFG(0)),
94         dump_register(GUSB2PHYCFG(1)),
95         dump_register(GUSB2PHYCFG(2)),
96         dump_register(GUSB2PHYCFG(3)),
97         dump_register(GUSB2PHYCFG(4)),
98         dump_register(GUSB2PHYCFG(5)),
99         dump_register(GUSB2PHYCFG(6)),
100         dump_register(GUSB2PHYCFG(7)),
101         dump_register(GUSB2PHYCFG(8)),
102         dump_register(GUSB2PHYCFG(9)),
103         dump_register(GUSB2PHYCFG(10)),
104         dump_register(GUSB2PHYCFG(11)),
105         dump_register(GUSB2PHYCFG(12)),
106         dump_register(GUSB2PHYCFG(13)),
107         dump_register(GUSB2PHYCFG(14)),
108         dump_register(GUSB2PHYCFG(15)),
109
110         dump_register(GUSB2I2CCTL(0)),
111         dump_register(GUSB2I2CCTL(1)),
112         dump_register(GUSB2I2CCTL(2)),
113         dump_register(GUSB2I2CCTL(3)),
114         dump_register(GUSB2I2CCTL(4)),
115         dump_register(GUSB2I2CCTL(5)),
116         dump_register(GUSB2I2CCTL(6)),
117         dump_register(GUSB2I2CCTL(7)),
118         dump_register(GUSB2I2CCTL(8)),
119         dump_register(GUSB2I2CCTL(9)),
120         dump_register(GUSB2I2CCTL(10)),
121         dump_register(GUSB2I2CCTL(11)),
122         dump_register(GUSB2I2CCTL(12)),
123         dump_register(GUSB2I2CCTL(13)),
124         dump_register(GUSB2I2CCTL(14)),
125         dump_register(GUSB2I2CCTL(15)),
126
127         dump_register(GUSB2PHYACC(0)),
128         dump_register(GUSB2PHYACC(1)),
129         dump_register(GUSB2PHYACC(2)),
130         dump_register(GUSB2PHYACC(3)),
131         dump_register(GUSB2PHYACC(4)),
132         dump_register(GUSB2PHYACC(5)),
133         dump_register(GUSB2PHYACC(6)),
134         dump_register(GUSB2PHYACC(7)),
135         dump_register(GUSB2PHYACC(8)),
136         dump_register(GUSB2PHYACC(9)),
137         dump_register(GUSB2PHYACC(10)),
138         dump_register(GUSB2PHYACC(11)),
139         dump_register(GUSB2PHYACC(12)),
140         dump_register(GUSB2PHYACC(13)),
141         dump_register(GUSB2PHYACC(14)),
142         dump_register(GUSB2PHYACC(15)),
143
144         dump_register(GUSB3PIPECTL(0)),
145         dump_register(GUSB3PIPECTL(1)),
146         dump_register(GUSB3PIPECTL(2)),
147         dump_register(GUSB3PIPECTL(3)),
148         dump_register(GUSB3PIPECTL(4)),
149         dump_register(GUSB3PIPECTL(5)),
150         dump_register(GUSB3PIPECTL(6)),
151         dump_register(GUSB3PIPECTL(7)),
152         dump_register(GUSB3PIPECTL(8)),
153         dump_register(GUSB3PIPECTL(9)),
154         dump_register(GUSB3PIPECTL(10)),
155         dump_register(GUSB3PIPECTL(11)),
156         dump_register(GUSB3PIPECTL(12)),
157         dump_register(GUSB3PIPECTL(13)),
158         dump_register(GUSB3PIPECTL(14)),
159         dump_register(GUSB3PIPECTL(15)),
160
161         dump_register(GTXFIFOSIZ(0)),
162         dump_register(GTXFIFOSIZ(1)),
163         dump_register(GTXFIFOSIZ(2)),
164         dump_register(GTXFIFOSIZ(3)),
165         dump_register(GTXFIFOSIZ(4)),
166         dump_register(GTXFIFOSIZ(5)),
167         dump_register(GTXFIFOSIZ(6)),
168         dump_register(GTXFIFOSIZ(7)),
169         dump_register(GTXFIFOSIZ(8)),
170         dump_register(GTXFIFOSIZ(9)),
171         dump_register(GTXFIFOSIZ(10)),
172         dump_register(GTXFIFOSIZ(11)),
173         dump_register(GTXFIFOSIZ(12)),
174         dump_register(GTXFIFOSIZ(13)),
175         dump_register(GTXFIFOSIZ(14)),
176         dump_register(GTXFIFOSIZ(15)),
177         dump_register(GTXFIFOSIZ(16)),
178         dump_register(GTXFIFOSIZ(17)),
179         dump_register(GTXFIFOSIZ(18)),
180         dump_register(GTXFIFOSIZ(19)),
181         dump_register(GTXFIFOSIZ(20)),
182         dump_register(GTXFIFOSIZ(21)),
183         dump_register(GTXFIFOSIZ(22)),
184         dump_register(GTXFIFOSIZ(23)),
185         dump_register(GTXFIFOSIZ(24)),
186         dump_register(GTXFIFOSIZ(25)),
187         dump_register(GTXFIFOSIZ(26)),
188         dump_register(GTXFIFOSIZ(27)),
189         dump_register(GTXFIFOSIZ(28)),
190         dump_register(GTXFIFOSIZ(29)),
191         dump_register(GTXFIFOSIZ(30)),
192         dump_register(GTXFIFOSIZ(31)),
193
194         dump_register(GRXFIFOSIZ(0)),
195         dump_register(GRXFIFOSIZ(1)),
196         dump_register(GRXFIFOSIZ(2)),
197         dump_register(GRXFIFOSIZ(3)),
198         dump_register(GRXFIFOSIZ(4)),
199         dump_register(GRXFIFOSIZ(5)),
200         dump_register(GRXFIFOSIZ(6)),
201         dump_register(GRXFIFOSIZ(7)),
202         dump_register(GRXFIFOSIZ(8)),
203         dump_register(GRXFIFOSIZ(9)),
204         dump_register(GRXFIFOSIZ(10)),
205         dump_register(GRXFIFOSIZ(11)),
206         dump_register(GRXFIFOSIZ(12)),
207         dump_register(GRXFIFOSIZ(13)),
208         dump_register(GRXFIFOSIZ(14)),
209         dump_register(GRXFIFOSIZ(15)),
210         dump_register(GRXFIFOSIZ(16)),
211         dump_register(GRXFIFOSIZ(17)),
212         dump_register(GRXFIFOSIZ(18)),
213         dump_register(GRXFIFOSIZ(19)),
214         dump_register(GRXFIFOSIZ(20)),
215         dump_register(GRXFIFOSIZ(21)),
216         dump_register(GRXFIFOSIZ(22)),
217         dump_register(GRXFIFOSIZ(23)),
218         dump_register(GRXFIFOSIZ(24)),
219         dump_register(GRXFIFOSIZ(25)),
220         dump_register(GRXFIFOSIZ(26)),
221         dump_register(GRXFIFOSIZ(27)),
222         dump_register(GRXFIFOSIZ(28)),
223         dump_register(GRXFIFOSIZ(29)),
224         dump_register(GRXFIFOSIZ(30)),
225         dump_register(GRXFIFOSIZ(31)),
226
227         dump_register(GEVNTADRLO(0)),
228         dump_register(GEVNTADRHI(0)),
229         dump_register(GEVNTSIZ(0)),
230         dump_register(GEVNTCOUNT(0)),
231
232         dump_register(GHWPARAMS8),
233         dump_register(DCFG),
234         dump_register(DCTL),
235         dump_register(DEVTEN),
236         dump_register(DSTS),
237         dump_register(DGCMDPAR),
238         dump_register(DGCMD),
239         dump_register(DALEPENA),
240
241         dump_register(DEPCMDPAR2(0)),
242         dump_register(DEPCMDPAR2(1)),
243         dump_register(DEPCMDPAR2(2)),
244         dump_register(DEPCMDPAR2(3)),
245         dump_register(DEPCMDPAR2(4)),
246         dump_register(DEPCMDPAR2(5)),
247         dump_register(DEPCMDPAR2(6)),
248         dump_register(DEPCMDPAR2(7)),
249         dump_register(DEPCMDPAR2(8)),
250         dump_register(DEPCMDPAR2(9)),
251         dump_register(DEPCMDPAR2(10)),
252         dump_register(DEPCMDPAR2(11)),
253         dump_register(DEPCMDPAR2(12)),
254         dump_register(DEPCMDPAR2(13)),
255         dump_register(DEPCMDPAR2(14)),
256         dump_register(DEPCMDPAR2(15)),
257         dump_register(DEPCMDPAR2(16)),
258         dump_register(DEPCMDPAR2(17)),
259         dump_register(DEPCMDPAR2(18)),
260         dump_register(DEPCMDPAR2(19)),
261         dump_register(DEPCMDPAR2(20)),
262         dump_register(DEPCMDPAR2(21)),
263         dump_register(DEPCMDPAR2(22)),
264         dump_register(DEPCMDPAR2(23)),
265         dump_register(DEPCMDPAR2(24)),
266         dump_register(DEPCMDPAR2(25)),
267         dump_register(DEPCMDPAR2(26)),
268         dump_register(DEPCMDPAR2(27)),
269         dump_register(DEPCMDPAR2(28)),
270         dump_register(DEPCMDPAR2(29)),
271         dump_register(DEPCMDPAR2(30)),
272         dump_register(DEPCMDPAR2(31)),
273
274         dump_register(DEPCMDPAR1(0)),
275         dump_register(DEPCMDPAR1(1)),
276         dump_register(DEPCMDPAR1(2)),
277         dump_register(DEPCMDPAR1(3)),
278         dump_register(DEPCMDPAR1(4)),
279         dump_register(DEPCMDPAR1(5)),
280         dump_register(DEPCMDPAR1(6)),
281         dump_register(DEPCMDPAR1(7)),
282         dump_register(DEPCMDPAR1(8)),
283         dump_register(DEPCMDPAR1(9)),
284         dump_register(DEPCMDPAR1(10)),
285         dump_register(DEPCMDPAR1(11)),
286         dump_register(DEPCMDPAR1(12)),
287         dump_register(DEPCMDPAR1(13)),
288         dump_register(DEPCMDPAR1(14)),
289         dump_register(DEPCMDPAR1(15)),
290         dump_register(DEPCMDPAR1(16)),
291         dump_register(DEPCMDPAR1(17)),
292         dump_register(DEPCMDPAR1(18)),
293         dump_register(DEPCMDPAR1(19)),
294         dump_register(DEPCMDPAR1(20)),
295         dump_register(DEPCMDPAR1(21)),
296         dump_register(DEPCMDPAR1(22)),
297         dump_register(DEPCMDPAR1(23)),
298         dump_register(DEPCMDPAR1(24)),
299         dump_register(DEPCMDPAR1(25)),
300         dump_register(DEPCMDPAR1(26)),
301         dump_register(DEPCMDPAR1(27)),
302         dump_register(DEPCMDPAR1(28)),
303         dump_register(DEPCMDPAR1(29)),
304         dump_register(DEPCMDPAR1(30)),
305         dump_register(DEPCMDPAR1(31)),
306
307         dump_register(DEPCMDPAR0(0)),
308         dump_register(DEPCMDPAR0(1)),
309         dump_register(DEPCMDPAR0(2)),
310         dump_register(DEPCMDPAR0(3)),
311         dump_register(DEPCMDPAR0(4)),
312         dump_register(DEPCMDPAR0(5)),
313         dump_register(DEPCMDPAR0(6)),
314         dump_register(DEPCMDPAR0(7)),
315         dump_register(DEPCMDPAR0(8)),
316         dump_register(DEPCMDPAR0(9)),
317         dump_register(DEPCMDPAR0(10)),
318         dump_register(DEPCMDPAR0(11)),
319         dump_register(DEPCMDPAR0(12)),
320         dump_register(DEPCMDPAR0(13)),
321         dump_register(DEPCMDPAR0(14)),
322         dump_register(DEPCMDPAR0(15)),
323         dump_register(DEPCMDPAR0(16)),
324         dump_register(DEPCMDPAR0(17)),
325         dump_register(DEPCMDPAR0(18)),
326         dump_register(DEPCMDPAR0(19)),
327         dump_register(DEPCMDPAR0(20)),
328         dump_register(DEPCMDPAR0(21)),
329         dump_register(DEPCMDPAR0(22)),
330         dump_register(DEPCMDPAR0(23)),
331         dump_register(DEPCMDPAR0(24)),
332         dump_register(DEPCMDPAR0(25)),
333         dump_register(DEPCMDPAR0(26)),
334         dump_register(DEPCMDPAR0(27)),
335         dump_register(DEPCMDPAR0(28)),
336         dump_register(DEPCMDPAR0(29)),
337         dump_register(DEPCMDPAR0(30)),
338         dump_register(DEPCMDPAR0(31)),
339
340         dump_register(DEPCMD(0)),
341         dump_register(DEPCMD(1)),
342         dump_register(DEPCMD(2)),
343         dump_register(DEPCMD(3)),
344         dump_register(DEPCMD(4)),
345         dump_register(DEPCMD(5)),
346         dump_register(DEPCMD(6)),
347         dump_register(DEPCMD(7)),
348         dump_register(DEPCMD(8)),
349         dump_register(DEPCMD(9)),
350         dump_register(DEPCMD(10)),
351         dump_register(DEPCMD(11)),
352         dump_register(DEPCMD(12)),
353         dump_register(DEPCMD(13)),
354         dump_register(DEPCMD(14)),
355         dump_register(DEPCMD(15)),
356         dump_register(DEPCMD(16)),
357         dump_register(DEPCMD(17)),
358         dump_register(DEPCMD(18)),
359         dump_register(DEPCMD(19)),
360         dump_register(DEPCMD(20)),
361         dump_register(DEPCMD(21)),
362         dump_register(DEPCMD(22)),
363         dump_register(DEPCMD(23)),
364         dump_register(DEPCMD(24)),
365         dump_register(DEPCMD(25)),
366         dump_register(DEPCMD(26)),
367         dump_register(DEPCMD(27)),
368         dump_register(DEPCMD(28)),
369         dump_register(DEPCMD(29)),
370         dump_register(DEPCMD(30)),
371         dump_register(DEPCMD(31)),
372
373         dump_register(OCFG),
374         dump_register(OCTL),
375         dump_register(OEVTEN),
376         dump_register(OSTS),
377 };
378
379 static int dwc3_regdump_show(struct seq_file *s, void *unused)
380 {
381         struct dwc3             *dwc = s->private;
382
383         seq_printf(s, "DesignWare USB3 Core Register Dump\n");
384         debugfs_print_regs32(s, dwc3_regs, ARRAY_SIZE(dwc3_regs),
385                              dwc->regs, "");
386         return 0;
387 }
388
389 static int dwc3_regdump_open(struct inode *inode, struct file *file)
390 {
391         return single_open(file, dwc3_regdump_show, inode->i_private);
392 }
393
394 static const struct file_operations dwc3_regdump_fops = {
395         .open                   = dwc3_regdump_open,
396         .read                   = seq_read,
397         .release                = single_release,
398 };
399
400 static int dwc3_mode_show(struct seq_file *s, void *unused)
401 {
402         struct dwc3             *dwc = s->private;
403         unsigned long           flags;
404         u32                     reg;
405
406         spin_lock_irqsave(&dwc->lock, flags);
407         reg = dwc3_readl(dwc->regs, DWC3_GCTL);
408         spin_unlock_irqrestore(&dwc->lock, flags);
409
410         switch (DWC3_GCTL_PRTCAP(reg)) {
411         case DWC3_GCTL_PRTCAP_HOST:
412                 seq_printf(s, "host\n");
413                 break;
414         case DWC3_GCTL_PRTCAP_DEVICE:
415                 seq_printf(s, "device\n");
416                 break;
417         case DWC3_GCTL_PRTCAP_OTG:
418                 seq_printf(s, "OTG\n");
419                 break;
420         default:
421                 seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg));
422         }
423
424         return 0;
425 }
426
427 static int dwc3_mode_open(struct inode *inode, struct file *file)
428 {
429         return single_open(file, dwc3_mode_show, inode->i_private);
430 }
431
432 static ssize_t dwc3_mode_write(struct file *file,
433                 const char __user *ubuf, size_t count, loff_t *ppos)
434 {
435         struct seq_file         *s = file->private_data;
436         struct dwc3             *dwc = s->private;
437         unsigned long           flags;
438         u32                     mode = 0;
439         char                    buf[32];
440
441         if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
442                 return -EFAULT;
443
444         if (!strncmp(buf, "host", 4))
445                 mode |= DWC3_GCTL_PRTCAP_HOST;
446
447         if (!strncmp(buf, "device", 6))
448                 mode |= DWC3_GCTL_PRTCAP_DEVICE;
449
450         if (!strncmp(buf, "otg", 3))
451                 mode |= DWC3_GCTL_PRTCAP_OTG;
452
453         if (mode) {
454                 spin_lock_irqsave(&dwc->lock, flags);
455                 dwc3_set_mode(dwc, mode);
456                 spin_unlock_irqrestore(&dwc->lock, flags);
457         }
458         return count;
459 }
460
461 static const struct file_operations dwc3_mode_fops = {
462         .open                   = dwc3_mode_open,
463         .write                  = dwc3_mode_write,
464         .read                   = seq_read,
465         .llseek                 = seq_lseek,
466         .release                = single_release,
467 };
468
469 static int dwc3_testmode_show(struct seq_file *s, void *unused)
470 {
471         struct dwc3             *dwc = s->private;
472         unsigned long           flags;
473         u32                     reg;
474
475         spin_lock_irqsave(&dwc->lock, flags);
476         reg = dwc3_readl(dwc->regs, DWC3_DCTL);
477         reg &= DWC3_DCTL_TSTCTRL_MASK;
478         reg >>= 1;
479         spin_unlock_irqrestore(&dwc->lock, flags);
480
481         switch (reg) {
482         case 0:
483                 seq_printf(s, "no test\n");
484                 break;
485         case TEST_J:
486                 seq_printf(s, "test_j\n");
487                 break;
488         case TEST_K:
489                 seq_printf(s, "test_k\n");
490                 break;
491         case TEST_SE0_NAK:
492                 seq_printf(s, "test_se0_nak\n");
493                 break;
494         case TEST_PACKET:
495                 seq_printf(s, "test_packet\n");
496                 break;
497         case TEST_FORCE_EN:
498                 seq_printf(s, "test_force_enable\n");
499                 break;
500         default:
501                 seq_printf(s, "UNKNOWN %d\n", reg);
502         }
503
504         return 0;
505 }
506
507 static int dwc3_testmode_open(struct inode *inode, struct file *file)
508 {
509         return single_open(file, dwc3_testmode_show, inode->i_private);
510 }
511
512 static ssize_t dwc3_testmode_write(struct file *file,
513                 const char __user *ubuf, size_t count, loff_t *ppos)
514 {
515         struct seq_file         *s = file->private_data;
516         struct dwc3             *dwc = s->private;
517         unsigned long           flags;
518         u32                     testmode = 0;
519         char                    buf[32];
520
521         if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
522                 return -EFAULT;
523
524         if (!strncmp(buf, "test_j", 6))
525                 testmode = TEST_J;
526         else if (!strncmp(buf, "test_k", 6))
527                 testmode = TEST_K;
528         else if (!strncmp(buf, "test_se0_nak", 12))
529                 testmode = TEST_SE0_NAK;
530         else if (!strncmp(buf, "test_packet", 11))
531                 testmode = TEST_PACKET;
532         else if (!strncmp(buf, "test_force_enable", 17))
533                 testmode = TEST_FORCE_EN;
534         else
535                 testmode = 0;
536
537         spin_lock_irqsave(&dwc->lock, flags);
538         if (dwc3_gadget_set_test_mode(dwc, testmode))
539                 dev_dbg(dwc->dev, "host: Invalid request\n");
540         spin_unlock_irqrestore(&dwc->lock, flags);
541
542         return count;
543 }
544
545 static const struct file_operations dwc3_testmode_fops = {
546         .open                   = dwc3_testmode_open,
547         .write                  = dwc3_testmode_write,
548         .read                   = seq_read,
549         .llseek                 = seq_lseek,
550         .release                = single_release,
551 };
552
553 static int dwc3_link_state_show(struct seq_file *s, void *unused)
554 {
555         struct dwc3             *dwc = s->private;
556         unsigned long           flags;
557         enum dwc3_link_state    state;
558         u32                     reg;
559
560         spin_lock_irqsave(&dwc->lock, flags);
561         reg = dwc3_readl(dwc->regs, DWC3_DSTS);
562         state = DWC3_DSTS_USBLNKST(reg);
563         spin_unlock_irqrestore(&dwc->lock, flags);
564
565         switch (state) {
566         case DWC3_LINK_STATE_U0:
567                 seq_printf(s, "U0\n");
568                 break;
569         case DWC3_LINK_STATE_U1:
570                 seq_printf(s, "U1\n");
571                 break;
572         case DWC3_LINK_STATE_U2:
573                 seq_printf(s, "U2\n");
574                 break;
575         case DWC3_LINK_STATE_U3:
576                 seq_printf(s, "U3\n");
577                 break;
578         case DWC3_LINK_STATE_SS_DIS:
579                 seq_printf(s, "SS.Disabled\n");
580                 break;
581         case DWC3_LINK_STATE_RX_DET:
582                 seq_printf(s, "Rx.Detect\n");
583                 break;
584         case DWC3_LINK_STATE_SS_INACT:
585                 seq_printf(s, "SS.Inactive\n");
586                 break;
587         case DWC3_LINK_STATE_POLL:
588                 seq_printf(s, "Poll\n");
589                 break;
590         case DWC3_LINK_STATE_RECOV:
591                 seq_printf(s, "Recovery\n");
592                 break;
593         case DWC3_LINK_STATE_HRESET:
594                 seq_printf(s, "HRESET\n");
595                 break;
596         case DWC3_LINK_STATE_CMPLY:
597                 seq_printf(s, "Compliance\n");
598                 break;
599         case DWC3_LINK_STATE_LPBK:
600                 seq_printf(s, "Loopback\n");
601                 break;
602         default:
603                 seq_printf(s, "UNKNOWN %d\n", reg);
604         }
605
606         return 0;
607 }
608
609 static int dwc3_link_state_open(struct inode *inode, struct file *file)
610 {
611         return single_open(file, dwc3_link_state_show, inode->i_private);
612 }
613
614 static ssize_t dwc3_link_state_write(struct file *file,
615                 const char __user *ubuf, size_t count, loff_t *ppos)
616 {
617         struct seq_file         *s = file->private_data;
618         struct dwc3             *dwc = s->private;
619         unsigned long           flags;
620         enum dwc3_link_state    state = 0;
621         char                    buf[32];
622
623         if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
624                 return -EFAULT;
625
626         if (!strncmp(buf, "SS.Disabled", 11))
627                 state = DWC3_LINK_STATE_SS_DIS;
628         else if (!strncmp(buf, "Rx.Detect", 9))
629                 state = DWC3_LINK_STATE_RX_DET;
630         else if (!strncmp(buf, "SS.Inactive", 11))
631                 state = DWC3_LINK_STATE_SS_INACT;
632         else if (!strncmp(buf, "Recovery", 8))
633                 state = DWC3_LINK_STATE_RECOV;
634         else if (!strncmp(buf, "Compliance", 10))
635                 state = DWC3_LINK_STATE_CMPLY;
636         else if (!strncmp(buf, "Loopback", 8))
637                 state = DWC3_LINK_STATE_LPBK;
638         else
639                 return -EINVAL;
640
641         spin_lock_irqsave(&dwc->lock, flags);
642         if (dwc3_gadget_set_link_state(dwc, state))
643                 dev_dbg(dwc->dev, "host: Invalid request\n");
644         spin_unlock_irqrestore(&dwc->lock, flags);
645
646         return count;
647 }
648
649 static const struct file_operations dwc3_link_state_fops = {
650         .open                   = dwc3_link_state_open,
651         .write                  = dwc3_link_state_write,
652         .read                   = seq_read,
653         .llseek                 = seq_lseek,
654         .release                = single_release,
655 };
656
657 int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
658 {
659         struct dentry           *root;
660         struct dentry           *file;
661         int                     ret;
662
663         root = debugfs_create_dir(dev_name(dwc->dev), NULL);
664         if (!root) {
665                 ret = -ENOMEM;
666                 goto err0;
667         }
668
669         dwc->root = root;
670
671         file = debugfs_create_file("regdump", S_IRUGO, root, dwc,
672                         &dwc3_regdump_fops);
673         if (!file) {
674                 ret = -ENOMEM;
675                 goto err1;
676         }
677
678         file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root,
679                         dwc, &dwc3_mode_fops);
680         if (!file) {
681                 ret = -ENOMEM;
682                 goto err1;
683         }
684
685         file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root,
686                         dwc, &dwc3_testmode_fops);
687         if (!file) {
688                 ret = -ENOMEM;
689                 goto err1;
690         }
691
692         file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root,
693                         dwc, &dwc3_link_state_fops);
694         if (!file) {
695                 ret = -ENOMEM;
696                 goto err1;
697         }
698
699         return 0;
700
701 err1:
702         debugfs_remove_recursive(root);
703
704 err0:
705         return ret;
706 }
707
708 void __devexit dwc3_debugfs_exit(struct dwc3 *dwc)
709 {
710         debugfs_remove_recursive(dwc->root);
711         dwc->root = NULL;
712 }