xref: /openbmc/linux/drivers/usb/dwc3/debugfs.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
15fd54aceSGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
227088e00SAditya Srivastava /*
372246da4SFelipe Balbi  * debugfs.c - DesignWare USB3 DRD Controller DebugFS file
472246da4SFelipe Balbi  *
510623b87SAlexander A. Klimov  * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
672246da4SFelipe Balbi  *
772246da4SFelipe Balbi  * Authors: Felipe Balbi <balbi@ti.com>,
872246da4SFelipe Balbi  *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
972246da4SFelipe Balbi  */
1072246da4SFelipe Balbi 
1172246da4SFelipe Balbi #include <linux/kernel.h>
1272246da4SFelipe Balbi #include <linux/slab.h>
1372246da4SFelipe Balbi #include <linux/ptrace.h>
1472246da4SFelipe Balbi #include <linux/types.h>
1572246da4SFelipe Balbi #include <linux/spinlock.h>
1672246da4SFelipe Balbi #include <linux/debugfs.h>
1772246da4SFelipe Balbi #include <linux/seq_file.h>
1872246da4SFelipe Balbi #include <linux/delay.h>
1925b8ff68SFelipe Balbi #include <linux/uaccess.h>
2072246da4SFelipe Balbi 
21080d921fSFelipe Balbi #include <linux/usb/ch9.h>
22080d921fSFelipe Balbi 
2372246da4SFelipe Balbi #include "core.h"
2472246da4SFelipe Balbi #include "gadget.h"
2572246da4SFelipe Balbi #include "io.h"
268becf270SFelipe Balbi #include "debug.h"
2772246da4SFelipe Balbi 
2862ba09d6SThinh Nguyen #define DWC3_LSP_MUX_UNSELECTED 0xfffff
2962ba09d6SThinh Nguyen 
3072246da4SFelipe Balbi #define dump_register(nm)				\
3172246da4SFelipe Balbi {							\
3272246da4SFelipe Balbi 	.name	= __stringify(nm),			\
332eb88016SFelipe Balbi 	.offset	= DWC3_ ##nm,				\
3472246da4SFelipe Balbi }
3572246da4SFelipe Balbi 
362eb88016SFelipe Balbi #define dump_ep_register_set(n)			\
372eb88016SFelipe Balbi 	{					\
382eb88016SFelipe Balbi 		.name = "DEPCMDPAR2("__stringify(n)")",	\
392eb88016SFelipe Balbi 		.offset = DWC3_DEP_BASE(n) +	\
402eb88016SFelipe Balbi 			DWC3_DEPCMDPAR2,	\
412eb88016SFelipe Balbi 	},					\
422eb88016SFelipe Balbi 	{					\
432eb88016SFelipe Balbi 		.name = "DEPCMDPAR1("__stringify(n)")",	\
442eb88016SFelipe Balbi 		.offset = DWC3_DEP_BASE(n) +	\
452eb88016SFelipe Balbi 			DWC3_DEPCMDPAR1,	\
462eb88016SFelipe Balbi 	},					\
472eb88016SFelipe Balbi 	{					\
482eb88016SFelipe Balbi 		.name = "DEPCMDPAR0("__stringify(n)")",	\
492eb88016SFelipe Balbi 		.offset = DWC3_DEP_BASE(n) +	\
502eb88016SFelipe Balbi 			DWC3_DEPCMDPAR0,	\
512eb88016SFelipe Balbi 	},					\
522eb88016SFelipe Balbi 	{					\
532eb88016SFelipe Balbi 		.name = "DEPCMD("__stringify(n)")",	\
542eb88016SFelipe Balbi 		.offset = DWC3_DEP_BASE(n) +	\
552eb88016SFelipe Balbi 			DWC3_DEPCMD,		\
562eb88016SFelipe Balbi 	}
572eb88016SFelipe Balbi 
582eb88016SFelipe Balbi 
594ec0ddb1SFelipe Balbi static const struct debugfs_reg32 dwc3_regs[] = {
6072246da4SFelipe Balbi 	dump_register(GSBUSCFG0),
6172246da4SFelipe Balbi 	dump_register(GSBUSCFG1),
6272246da4SFelipe Balbi 	dump_register(GTXTHRCFG),
6372246da4SFelipe Balbi 	dump_register(GRXTHRCFG),
6472246da4SFelipe Balbi 	dump_register(GCTL),
6572246da4SFelipe Balbi 	dump_register(GEVTEN),
6672246da4SFelipe Balbi 	dump_register(GSTS),
67475c8bebSWilliam Wu 	dump_register(GUCTL1),
6872246da4SFelipe Balbi 	dump_register(GSNPSID),
6972246da4SFelipe Balbi 	dump_register(GGPIO),
7072246da4SFelipe Balbi 	dump_register(GUID),
7172246da4SFelipe Balbi 	dump_register(GUCTL),
7272246da4SFelipe Balbi 	dump_register(GBUSERRADDR0),
7372246da4SFelipe Balbi 	dump_register(GBUSERRADDR1),
7472246da4SFelipe Balbi 	dump_register(GPRTBIMAP0),
7572246da4SFelipe Balbi 	dump_register(GPRTBIMAP1),
7672246da4SFelipe Balbi 	dump_register(GHWPARAMS0),
7772246da4SFelipe Balbi 	dump_register(GHWPARAMS1),
7872246da4SFelipe Balbi 	dump_register(GHWPARAMS2),
7972246da4SFelipe Balbi 	dump_register(GHWPARAMS3),
8072246da4SFelipe Balbi 	dump_register(GHWPARAMS4),
8172246da4SFelipe Balbi 	dump_register(GHWPARAMS5),
8272246da4SFelipe Balbi 	dump_register(GHWPARAMS6),
8372246da4SFelipe Balbi 	dump_register(GHWPARAMS7),
8472246da4SFelipe Balbi 	dump_register(GDBGFIFOSPACE),
8572246da4SFelipe Balbi 	dump_register(GDBGLTSSM),
8680b77634SThinh Nguyen 	dump_register(GDBGBMU),
8772246da4SFelipe Balbi 	dump_register(GPRTBIMAP_HS0),
8872246da4SFelipe Balbi 	dump_register(GPRTBIMAP_HS1),
8972246da4SFelipe Balbi 	dump_register(GPRTBIMAP_FS0),
9072246da4SFelipe Balbi 	dump_register(GPRTBIMAP_FS1),
918c4853c4SLi Jun 	dump_register(GUCTL2),
928c4853c4SLi Jun 	dump_register(VER_NUMBER),
938c4853c4SLi Jun 	dump_register(VER_TYPE),
9472246da4SFelipe Balbi 
9572246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(0)),
9672246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(1)),
9772246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(2)),
9872246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(3)),
9972246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(4)),
10072246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(5)),
10172246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(6)),
10272246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(7)),
10372246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(8)),
10472246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(9)),
10572246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(10)),
10672246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(11)),
10772246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(12)),
10872246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(13)),
10972246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(14)),
11072246da4SFelipe Balbi 	dump_register(GUSB2PHYCFG(15)),
11172246da4SFelipe Balbi 
11272246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(0)),
11372246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(1)),
11472246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(2)),
11572246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(3)),
11672246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(4)),
11772246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(5)),
11872246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(6)),
11972246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(7)),
12072246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(8)),
12172246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(9)),
12272246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(10)),
12372246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(11)),
12472246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(12)),
12572246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(13)),
12672246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(14)),
12772246da4SFelipe Balbi 	dump_register(GUSB2I2CCTL(15)),
12872246da4SFelipe Balbi 
12972246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(0)),
13072246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(1)),
13172246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(2)),
13272246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(3)),
13372246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(4)),
13472246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(5)),
13572246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(6)),
13672246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(7)),
13772246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(8)),
13872246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(9)),
13972246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(10)),
14072246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(11)),
14172246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(12)),
14272246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(13)),
14372246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(14)),
14472246da4SFelipe Balbi 	dump_register(GUSB2PHYACC(15)),
14572246da4SFelipe Balbi 
14672246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(0)),
14772246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(1)),
14872246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(2)),
14972246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(3)),
15072246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(4)),
15172246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(5)),
15272246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(6)),
15372246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(7)),
15472246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(8)),
15572246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(9)),
15672246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(10)),
15772246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(11)),
15872246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(12)),
15972246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(13)),
16072246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(14)),
16172246da4SFelipe Balbi 	dump_register(GUSB3PIPECTL(15)),
16272246da4SFelipe Balbi 
16372246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(0)),
16472246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(1)),
16572246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(2)),
16672246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(3)),
16772246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(4)),
16872246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(5)),
16972246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(6)),
17072246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(7)),
17172246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(8)),
17272246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(9)),
17372246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(10)),
17472246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(11)),
17572246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(12)),
17672246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(13)),
17772246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(14)),
17872246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(15)),
17972246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(16)),
18072246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(17)),
18172246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(18)),
18272246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(19)),
18372246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(20)),
18472246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(21)),
18572246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(22)),
18672246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(23)),
18772246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(24)),
18872246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(25)),
18972246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(26)),
19072246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(27)),
19172246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(28)),
19272246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(29)),
19372246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(30)),
19472246da4SFelipe Balbi 	dump_register(GTXFIFOSIZ(31)),
19572246da4SFelipe Balbi 
19672246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(0)),
19772246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(1)),
19872246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(2)),
19972246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(3)),
20072246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(4)),
20172246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(5)),
20272246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(6)),
20372246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(7)),
20472246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(8)),
20572246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(9)),
20672246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(10)),
20772246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(11)),
20872246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(12)),
20972246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(13)),
21072246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(14)),
21172246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(15)),
21272246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(16)),
21372246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(17)),
21472246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(18)),
21572246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(19)),
21672246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(20)),
21772246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(21)),
21872246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(22)),
21972246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(23)),
22072246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(24)),
22172246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(25)),
22272246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(26)),
22372246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(27)),
22472246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(28)),
22572246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(29)),
22672246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(30)),
22772246da4SFelipe Balbi 	dump_register(GRXFIFOSIZ(31)),
22872246da4SFelipe Balbi 
22972246da4SFelipe Balbi 	dump_register(GEVNTADRLO(0)),
23072246da4SFelipe Balbi 	dump_register(GEVNTADRHI(0)),
23172246da4SFelipe Balbi 	dump_register(GEVNTSIZ(0)),
23272246da4SFelipe Balbi 	dump_register(GEVNTCOUNT(0)),
23372246da4SFelipe Balbi 
23472246da4SFelipe Balbi 	dump_register(GHWPARAMS8),
2358c4853c4SLi Jun 	dump_register(GUCTL3),
2368c4853c4SLi Jun 	dump_register(GFLADJ),
23772246da4SFelipe Balbi 	dump_register(DCFG),
23872246da4SFelipe Balbi 	dump_register(DCTL),
23972246da4SFelipe Balbi 	dump_register(DEVTEN),
24072246da4SFelipe Balbi 	dump_register(DSTS),
24172246da4SFelipe Balbi 	dump_register(DGCMDPAR),
24272246da4SFelipe Balbi 	dump_register(DGCMD),
24372246da4SFelipe Balbi 	dump_register(DALEPENA),
24472246da4SFelipe Balbi 
2452eb88016SFelipe Balbi 	dump_ep_register_set(0),
2462eb88016SFelipe Balbi 	dump_ep_register_set(1),
2472eb88016SFelipe Balbi 	dump_ep_register_set(2),
2482eb88016SFelipe Balbi 	dump_ep_register_set(3),
2492eb88016SFelipe Balbi 	dump_ep_register_set(4),
2502eb88016SFelipe Balbi 	dump_ep_register_set(5),
2512eb88016SFelipe Balbi 	dump_ep_register_set(6),
2522eb88016SFelipe Balbi 	dump_ep_register_set(7),
2532eb88016SFelipe Balbi 	dump_ep_register_set(8),
2542eb88016SFelipe Balbi 	dump_ep_register_set(9),
2552eb88016SFelipe Balbi 	dump_ep_register_set(10),
2562eb88016SFelipe Balbi 	dump_ep_register_set(11),
2572eb88016SFelipe Balbi 	dump_ep_register_set(12),
2582eb88016SFelipe Balbi 	dump_ep_register_set(13),
2592eb88016SFelipe Balbi 	dump_ep_register_set(14),
2602eb88016SFelipe Balbi 	dump_ep_register_set(15),
2612eb88016SFelipe Balbi 	dump_ep_register_set(16),
2622eb88016SFelipe Balbi 	dump_ep_register_set(17),
2632eb88016SFelipe Balbi 	dump_ep_register_set(18),
2642eb88016SFelipe Balbi 	dump_ep_register_set(19),
2652eb88016SFelipe Balbi 	dump_ep_register_set(20),
2662eb88016SFelipe Balbi 	dump_ep_register_set(21),
2672eb88016SFelipe Balbi 	dump_ep_register_set(22),
2682eb88016SFelipe Balbi 	dump_ep_register_set(23),
2692eb88016SFelipe Balbi 	dump_ep_register_set(24),
2702eb88016SFelipe Balbi 	dump_ep_register_set(25),
2712eb88016SFelipe Balbi 	dump_ep_register_set(26),
2722eb88016SFelipe Balbi 	dump_ep_register_set(27),
2732eb88016SFelipe Balbi 	dump_ep_register_set(28),
2742eb88016SFelipe Balbi 	dump_ep_register_set(29),
2752eb88016SFelipe Balbi 	dump_ep_register_set(30),
2762eb88016SFelipe Balbi 	dump_ep_register_set(31),
27772246da4SFelipe Balbi 
27872246da4SFelipe Balbi 	dump_register(OCFG),
27972246da4SFelipe Balbi 	dump_register(OCTL),
280d4436c3aSGeorge Cherian 	dump_register(OEVT),
28172246da4SFelipe Balbi 	dump_register(OEVTEN),
28272246da4SFelipe Balbi 	dump_register(OSTS),
28372246da4SFelipe Balbi };
28472246da4SFelipe Balbi 
dwc3_host_lsp(struct seq_file * s)28562ba09d6SThinh Nguyen static void dwc3_host_lsp(struct seq_file *s)
28662ba09d6SThinh Nguyen {
28762ba09d6SThinh Nguyen 	struct dwc3		*dwc = s->private;
28862ba09d6SThinh Nguyen 	bool			dbc_enabled;
28962ba09d6SThinh Nguyen 	u32			sel;
29062ba09d6SThinh Nguyen 	u32			reg;
29162ba09d6SThinh Nguyen 	u32			val;
29262ba09d6SThinh Nguyen 
29362ba09d6SThinh Nguyen 	dbc_enabled = !!(dwc->hwparams.hwparams1 & DWC3_GHWPARAMS1_ENDBC);
29462ba09d6SThinh Nguyen 
29562ba09d6SThinh Nguyen 	sel = dwc->dbg_lsp_select;
29662ba09d6SThinh Nguyen 	if (sel == DWC3_LSP_MUX_UNSELECTED) {
29762ba09d6SThinh Nguyen 		seq_puts(s, "Write LSP selection to print for host\n");
29862ba09d6SThinh Nguyen 		return;
29962ba09d6SThinh Nguyen 	}
30062ba09d6SThinh Nguyen 
30162ba09d6SThinh Nguyen 	reg = DWC3_GDBGLSPMUX_HOSTSELECT(sel);
30262ba09d6SThinh Nguyen 
30362ba09d6SThinh Nguyen 	dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
30462ba09d6SThinh Nguyen 	val = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
30562ba09d6SThinh Nguyen 	seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", sel, val);
30662ba09d6SThinh Nguyen 
30762ba09d6SThinh Nguyen 	if (dbc_enabled && sel < 256) {
30862ba09d6SThinh Nguyen 		reg |= DWC3_GDBGLSPMUX_ENDBC;
30962ba09d6SThinh Nguyen 		dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
31062ba09d6SThinh Nguyen 		val = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
31162ba09d6SThinh Nguyen 		seq_printf(s, "GDBGLSP_DBC[%d] = 0x%08x\n", sel, val);
31262ba09d6SThinh Nguyen 	}
31362ba09d6SThinh Nguyen }
31462ba09d6SThinh Nguyen 
dwc3_gadget_lsp(struct seq_file * s)31562ba09d6SThinh Nguyen static void dwc3_gadget_lsp(struct seq_file *s)
31662ba09d6SThinh Nguyen {
31762ba09d6SThinh Nguyen 	struct dwc3		*dwc = s->private;
31862ba09d6SThinh Nguyen 	int			i;
31962ba09d6SThinh Nguyen 	u32			reg;
32062ba09d6SThinh Nguyen 
32162ba09d6SThinh Nguyen 	for (i = 0; i < 16; i++) {
32262ba09d6SThinh Nguyen 		reg = DWC3_GDBGLSPMUX_DEVSELECT(i);
32362ba09d6SThinh Nguyen 		dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
32462ba09d6SThinh Nguyen 		reg = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
32562ba09d6SThinh Nguyen 		seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", i, reg);
32662ba09d6SThinh Nguyen 	}
32762ba09d6SThinh Nguyen }
32862ba09d6SThinh Nguyen 
dwc3_lsp_show(struct seq_file * s,void * unused)32962ba09d6SThinh Nguyen static int dwc3_lsp_show(struct seq_file *s, void *unused)
33062ba09d6SThinh Nguyen {
33162ba09d6SThinh Nguyen 	struct dwc3		*dwc = s->private;
33262ba09d6SThinh Nguyen 	unsigned int		current_mode;
33362ba09d6SThinh Nguyen 	unsigned long		flags;
33462ba09d6SThinh Nguyen 	u32			reg;
335*614ce6a2SUdipto Goswami 	int			ret;
336*614ce6a2SUdipto Goswami 
337*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
338*614ce6a2SUdipto Goswami 	if (ret < 0)
339*614ce6a2SUdipto Goswami 		return ret;
34062ba09d6SThinh Nguyen 
34162ba09d6SThinh Nguyen 	spin_lock_irqsave(&dwc->lock, flags);
34262ba09d6SThinh Nguyen 	reg = dwc3_readl(dwc->regs, DWC3_GSTS);
34362ba09d6SThinh Nguyen 	current_mode = DWC3_GSTS_CURMOD(reg);
34462ba09d6SThinh Nguyen 
34562ba09d6SThinh Nguyen 	switch (current_mode) {
34662ba09d6SThinh Nguyen 	case DWC3_GSTS_CURMOD_HOST:
34762ba09d6SThinh Nguyen 		dwc3_host_lsp(s);
34862ba09d6SThinh Nguyen 		break;
34962ba09d6SThinh Nguyen 	case DWC3_GSTS_CURMOD_DEVICE:
35062ba09d6SThinh Nguyen 		dwc3_gadget_lsp(s);
35162ba09d6SThinh Nguyen 		break;
35262ba09d6SThinh Nguyen 	default:
35362ba09d6SThinh Nguyen 		seq_puts(s, "Mode is unknown, no LSP register printed\n");
35462ba09d6SThinh Nguyen 		break;
35562ba09d6SThinh Nguyen 	}
35662ba09d6SThinh Nguyen 	spin_unlock_irqrestore(&dwc->lock, flags);
35762ba09d6SThinh Nguyen 
358*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
359*614ce6a2SUdipto Goswami 
36062ba09d6SThinh Nguyen 	return 0;
36162ba09d6SThinh Nguyen }
36262ba09d6SThinh Nguyen 
dwc3_lsp_open(struct inode * inode,struct file * file)36362ba09d6SThinh Nguyen static int dwc3_lsp_open(struct inode *inode, struct file *file)
36462ba09d6SThinh Nguyen {
36562ba09d6SThinh Nguyen 	return single_open(file, dwc3_lsp_show, inode->i_private);
36662ba09d6SThinh Nguyen }
36762ba09d6SThinh Nguyen 
dwc3_lsp_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)36862ba09d6SThinh Nguyen static ssize_t dwc3_lsp_write(struct file *file, const char __user *ubuf,
36962ba09d6SThinh Nguyen 			      size_t count, loff_t *ppos)
37062ba09d6SThinh Nguyen {
37162ba09d6SThinh Nguyen 	struct seq_file		*s = file->private_data;
37262ba09d6SThinh Nguyen 	struct dwc3		*dwc = s->private;
37362ba09d6SThinh Nguyen 	unsigned long		flags;
37462ba09d6SThinh Nguyen 	char			buf[32] = { 0 };
37562ba09d6SThinh Nguyen 	u32			sel;
37662ba09d6SThinh Nguyen 	int			ret;
37762ba09d6SThinh Nguyen 
37862ba09d6SThinh Nguyen 	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
37962ba09d6SThinh Nguyen 		return -EFAULT;
38062ba09d6SThinh Nguyen 
38162ba09d6SThinh Nguyen 	ret = kstrtouint(buf, 0, &sel);
38262ba09d6SThinh Nguyen 	if (ret)
38362ba09d6SThinh Nguyen 		return ret;
38462ba09d6SThinh Nguyen 
38562ba09d6SThinh Nguyen 	spin_lock_irqsave(&dwc->lock, flags);
38662ba09d6SThinh Nguyen 	dwc->dbg_lsp_select = sel;
38762ba09d6SThinh Nguyen 	spin_unlock_irqrestore(&dwc->lock, flags);
38862ba09d6SThinh Nguyen 
38962ba09d6SThinh Nguyen 	return count;
39062ba09d6SThinh Nguyen }
39162ba09d6SThinh Nguyen 
39262ba09d6SThinh Nguyen static const struct file_operations dwc3_lsp_fops = {
39362ba09d6SThinh Nguyen 	.open			= dwc3_lsp_open,
39462ba09d6SThinh Nguyen 	.write			= dwc3_lsp_write,
39562ba09d6SThinh Nguyen 	.read			= seq_read,
39662ba09d6SThinh Nguyen 	.llseek			= seq_lseek,
39762ba09d6SThinh Nguyen 	.release		= single_release,
39862ba09d6SThinh Nguyen };
39962ba09d6SThinh Nguyen 
dwc3_mode_show(struct seq_file * s,void * unused)4000b9fe32dSFelipe Balbi static int dwc3_mode_show(struct seq_file *s, void *unused)
4010b9fe32dSFelipe Balbi {
4020b9fe32dSFelipe Balbi 	struct dwc3		*dwc = s->private;
4030b9fe32dSFelipe Balbi 	unsigned long		flags;
4040b9fe32dSFelipe Balbi 	u32			reg;
405*614ce6a2SUdipto Goswami 	int			ret;
406*614ce6a2SUdipto Goswami 
407*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
408*614ce6a2SUdipto Goswami 	if (ret < 0)
409*614ce6a2SUdipto Goswami 		return ret;
4100b9fe32dSFelipe Balbi 
4110b9fe32dSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
4120b9fe32dSFelipe Balbi 	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
4130b9fe32dSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
4140b9fe32dSFelipe Balbi 
4150b9fe32dSFelipe Balbi 	switch (DWC3_GCTL_PRTCAP(reg)) {
4160b9fe32dSFelipe Balbi 	case DWC3_GCTL_PRTCAP_HOST:
4179ae0eb45SFelipe Balbi 		seq_puts(s, "host\n");
4180b9fe32dSFelipe Balbi 		break;
4190b9fe32dSFelipe Balbi 	case DWC3_GCTL_PRTCAP_DEVICE:
4209ae0eb45SFelipe Balbi 		seq_puts(s, "device\n");
4210b9fe32dSFelipe Balbi 		break;
4220b9fe32dSFelipe Balbi 	case DWC3_GCTL_PRTCAP_OTG:
4239ae0eb45SFelipe Balbi 		seq_puts(s, "otg\n");
4240b9fe32dSFelipe Balbi 		break;
4250b9fe32dSFelipe Balbi 	default:
4260b9fe32dSFelipe Balbi 		seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg));
4270b9fe32dSFelipe Balbi 	}
4280b9fe32dSFelipe Balbi 
429*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
430*614ce6a2SUdipto Goswami 
4310b9fe32dSFelipe Balbi 	return 0;
4320b9fe32dSFelipe Balbi }
4330b9fe32dSFelipe Balbi 
dwc3_mode_open(struct inode * inode,struct file * file)4340b9fe32dSFelipe Balbi static int dwc3_mode_open(struct inode *inode, struct file *file)
4350b9fe32dSFelipe Balbi {
4360b9fe32dSFelipe Balbi 	return single_open(file, dwc3_mode_show, inode->i_private);
4370b9fe32dSFelipe Balbi }
4380b9fe32dSFelipe Balbi 
dwc3_mode_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)4390b9fe32dSFelipe Balbi static ssize_t dwc3_mode_write(struct file *file,
4400b9fe32dSFelipe Balbi 		const char __user *ubuf, size_t count, loff_t *ppos)
4410b9fe32dSFelipe Balbi {
4420b9fe32dSFelipe Balbi 	struct seq_file		*s = file->private_data;
4430b9fe32dSFelipe Balbi 	struct dwc3		*dwc = s->private;
4443140e8cbSSebastian Andrzej Siewior 	u32			mode = 0;
4450b9fe32dSFelipe Balbi 	char			buf[32];
4460b9fe32dSFelipe Balbi 
4470b9fe32dSFelipe Balbi 	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
4480b9fe32dSFelipe Balbi 		return -EFAULT;
4490b9fe32dSFelipe Balbi 
4505bde3f02SLi Jun 	if (dwc->dr_mode != USB_DR_MODE_OTG)
4515bde3f02SLi Jun 		return count;
4525bde3f02SLi Jun 
4530b9fe32dSFelipe Balbi 	if (!strncmp(buf, "host", 4))
454b202c42cSRoger Quadros 		mode = DWC3_GCTL_PRTCAP_HOST;
4550b9fe32dSFelipe Balbi 
4560b9fe32dSFelipe Balbi 	if (!strncmp(buf, "device", 6))
457b202c42cSRoger Quadros 		mode = DWC3_GCTL_PRTCAP_DEVICE;
4580b9fe32dSFelipe Balbi 
4590b9fe32dSFelipe Balbi 	if (!strncmp(buf, "otg", 3))
460b202c42cSRoger Quadros 		mode = DWC3_GCTL_PRTCAP_OTG;
4610b9fe32dSFelipe Balbi 
4623140e8cbSSebastian Andrzej Siewior 	dwc3_set_mode(dwc, mode);
46341ce1456SRoger Quadros 
4640b9fe32dSFelipe Balbi 	return count;
4650b9fe32dSFelipe Balbi }
4660b9fe32dSFelipe Balbi 
4670b9fe32dSFelipe Balbi static const struct file_operations dwc3_mode_fops = {
4680b9fe32dSFelipe Balbi 	.open			= dwc3_mode_open,
4690b9fe32dSFelipe Balbi 	.write			= dwc3_mode_write,
4700b9fe32dSFelipe Balbi 	.read			= seq_read,
4710b9fe32dSFelipe Balbi 	.llseek			= seq_lseek,
4720b9fe32dSFelipe Balbi 	.release		= single_release,
4730b9fe32dSFelipe Balbi };
4740b9fe32dSFelipe Balbi 
dwc3_testmode_show(struct seq_file * s,void * unused)475080d921fSFelipe Balbi static int dwc3_testmode_show(struct seq_file *s, void *unused)
476080d921fSFelipe Balbi {
477080d921fSFelipe Balbi 	struct dwc3		*dwc = s->private;
478080d921fSFelipe Balbi 	unsigned long		flags;
479080d921fSFelipe Balbi 	u32			reg;
480*614ce6a2SUdipto Goswami 	int			ret;
481*614ce6a2SUdipto Goswami 
482*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
483*614ce6a2SUdipto Goswami 	if (ret < 0)
484*614ce6a2SUdipto Goswami 		return ret;
485080d921fSFelipe Balbi 
486080d921fSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
487080d921fSFelipe Balbi 	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
488080d921fSFelipe Balbi 	reg &= DWC3_DCTL_TSTCTRL_MASK;
489080d921fSFelipe Balbi 	reg >>= 1;
490080d921fSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
491080d921fSFelipe Balbi 
492080d921fSFelipe Balbi 	switch (reg) {
493080d921fSFelipe Balbi 	case 0:
4949ae0eb45SFelipe Balbi 		seq_puts(s, "no test\n");
495080d921fSFelipe Balbi 		break;
49662fb45d3SGreg Kroah-Hartman 	case USB_TEST_J:
4979ae0eb45SFelipe Balbi 		seq_puts(s, "test_j\n");
498080d921fSFelipe Balbi 		break;
49962fb45d3SGreg Kroah-Hartman 	case USB_TEST_K:
5009ae0eb45SFelipe Balbi 		seq_puts(s, "test_k\n");
501080d921fSFelipe Balbi 		break;
50262fb45d3SGreg Kroah-Hartman 	case USB_TEST_SE0_NAK:
5039ae0eb45SFelipe Balbi 		seq_puts(s, "test_se0_nak\n");
504080d921fSFelipe Balbi 		break;
50562fb45d3SGreg Kroah-Hartman 	case USB_TEST_PACKET:
5069ae0eb45SFelipe Balbi 		seq_puts(s, "test_packet\n");
507080d921fSFelipe Balbi 		break;
50862fb45d3SGreg Kroah-Hartman 	case USB_TEST_FORCE_ENABLE:
5099ae0eb45SFelipe Balbi 		seq_puts(s, "test_force_enable\n");
510080d921fSFelipe Balbi 		break;
511080d921fSFelipe Balbi 	default:
512080d921fSFelipe Balbi 		seq_printf(s, "UNKNOWN %d\n", reg);
513080d921fSFelipe Balbi 	}
514080d921fSFelipe Balbi 
515*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
516*614ce6a2SUdipto Goswami 
517080d921fSFelipe Balbi 	return 0;
518080d921fSFelipe Balbi }
519080d921fSFelipe Balbi 
dwc3_testmode_open(struct inode * inode,struct file * file)520080d921fSFelipe Balbi static int dwc3_testmode_open(struct inode *inode, struct file *file)
521080d921fSFelipe Balbi {
522080d921fSFelipe Balbi 	return single_open(file, dwc3_testmode_show, inode->i_private);
523080d921fSFelipe Balbi }
524080d921fSFelipe Balbi 
dwc3_testmode_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)525080d921fSFelipe Balbi static ssize_t dwc3_testmode_write(struct file *file,
526080d921fSFelipe Balbi 		const char __user *ubuf, size_t count, loff_t *ppos)
527080d921fSFelipe Balbi {
528080d921fSFelipe Balbi 	struct seq_file		*s = file->private_data;
529080d921fSFelipe Balbi 	struct dwc3		*dwc = s->private;
530080d921fSFelipe Balbi 	unsigned long		flags;
531080d921fSFelipe Balbi 	u32			testmode = 0;
532080d921fSFelipe Balbi 	char			buf[32];
533*614ce6a2SUdipto Goswami 	int			ret;
534080d921fSFelipe Balbi 
535080d921fSFelipe Balbi 	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
536080d921fSFelipe Balbi 		return -EFAULT;
537080d921fSFelipe Balbi 
538080d921fSFelipe Balbi 	if (!strncmp(buf, "test_j", 6))
53962fb45d3SGreg Kroah-Hartman 		testmode = USB_TEST_J;
540080d921fSFelipe Balbi 	else if (!strncmp(buf, "test_k", 6))
54162fb45d3SGreg Kroah-Hartman 		testmode = USB_TEST_K;
54209072543SGerard Cauvy 	else if (!strncmp(buf, "test_se0_nak", 12))
54362fb45d3SGreg Kroah-Hartman 		testmode = USB_TEST_SE0_NAK;
54409072543SGerard Cauvy 	else if (!strncmp(buf, "test_packet", 11))
54562fb45d3SGreg Kroah-Hartman 		testmode = USB_TEST_PACKET;
54609072543SGerard Cauvy 	else if (!strncmp(buf, "test_force_enable", 17))
54762fb45d3SGreg Kroah-Hartman 		testmode = USB_TEST_FORCE_ENABLE;
548080d921fSFelipe Balbi 	else
549080d921fSFelipe Balbi 		testmode = 0;
550080d921fSFelipe Balbi 
551*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
552*614ce6a2SUdipto Goswami 	if (ret < 0)
553*614ce6a2SUdipto Goswami 		return ret;
554*614ce6a2SUdipto Goswami 
555080d921fSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
556080d921fSFelipe Balbi 	dwc3_gadget_set_test_mode(dwc, testmode);
557080d921fSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
558080d921fSFelipe Balbi 
559*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
560*614ce6a2SUdipto Goswami 
561080d921fSFelipe Balbi 	return count;
562080d921fSFelipe Balbi }
563080d921fSFelipe Balbi 
564080d921fSFelipe Balbi static const struct file_operations dwc3_testmode_fops = {
565080d921fSFelipe Balbi 	.open			= dwc3_testmode_open,
566080d921fSFelipe Balbi 	.write			= dwc3_testmode_write,
567080d921fSFelipe Balbi 	.read			= seq_read,
568080d921fSFelipe Balbi 	.llseek			= seq_lseek,
569080d921fSFelipe Balbi 	.release		= single_release,
570080d921fSFelipe Balbi };
571080d921fSFelipe Balbi 
dwc3_link_state_show(struct seq_file * s,void * unused)572138801aaSFelipe Balbi static int dwc3_link_state_show(struct seq_file *s, void *unused)
573138801aaSFelipe Balbi {
574138801aaSFelipe Balbi 	struct dwc3		*dwc = s->private;
575138801aaSFelipe Balbi 	unsigned long		flags;
576138801aaSFelipe Balbi 	enum dwc3_link_state	state;
577138801aaSFelipe Balbi 	u32			reg;
5780d36dedeSThinh Nguyen 	u8			speed;
579*614ce6a2SUdipto Goswami 	int			ret;
580*614ce6a2SUdipto Goswami 
581*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
582*614ce6a2SUdipto Goswami 	if (ret < 0)
583*614ce6a2SUdipto Goswami 		return ret;
584138801aaSFelipe Balbi 
585138801aaSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
586d102444cSThinh Nguyen 	reg = dwc3_readl(dwc->regs, DWC3_GSTS);
587d102444cSThinh Nguyen 	if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
588d102444cSThinh Nguyen 		seq_puts(s, "Not available\n");
589d102444cSThinh Nguyen 		spin_unlock_irqrestore(&dwc->lock, flags);
590*614ce6a2SUdipto Goswami 		pm_runtime_put_sync(dwc->dev);
591d102444cSThinh Nguyen 		return 0;
592d102444cSThinh Nguyen 	}
593d102444cSThinh Nguyen 
594138801aaSFelipe Balbi 	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
595138801aaSFelipe Balbi 	state = DWC3_DSTS_USBLNKST(reg);
5960d36dedeSThinh Nguyen 	speed = reg & DWC3_DSTS_CONNECTSPD;
597138801aaSFelipe Balbi 
5980d36dedeSThinh Nguyen 	seq_printf(s, "%s\n", (speed >= DWC3_DSTS_SUPERSPEED) ?
5990d36dedeSThinh Nguyen 		   dwc3_gadget_link_string(state) :
6000d36dedeSThinh Nguyen 		   dwc3_gadget_hs_link_string(state));
6010d36dedeSThinh Nguyen 	spin_unlock_irqrestore(&dwc->lock, flags);
602138801aaSFelipe Balbi 
603*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
604*614ce6a2SUdipto Goswami 
605138801aaSFelipe Balbi 	return 0;
606138801aaSFelipe Balbi }
607138801aaSFelipe Balbi 
dwc3_link_state_open(struct inode * inode,struct file * file)608138801aaSFelipe Balbi static int dwc3_link_state_open(struct inode *inode, struct file *file)
609138801aaSFelipe Balbi {
610138801aaSFelipe Balbi 	return single_open(file, dwc3_link_state_show, inode->i_private);
611138801aaSFelipe Balbi }
612138801aaSFelipe Balbi 
dwc3_link_state_write(struct file * file,const char __user * ubuf,size_t count,loff_t * ppos)613138801aaSFelipe Balbi static ssize_t dwc3_link_state_write(struct file *file,
614138801aaSFelipe Balbi 		const char __user *ubuf, size_t count, loff_t *ppos)
615138801aaSFelipe Balbi {
616138801aaSFelipe Balbi 	struct seq_file		*s = file->private_data;
617138801aaSFelipe Balbi 	struct dwc3		*dwc = s->private;
618138801aaSFelipe Balbi 	unsigned long		flags;
619138801aaSFelipe Balbi 	enum dwc3_link_state	state = 0;
620138801aaSFelipe Balbi 	char			buf[32];
6210d36dedeSThinh Nguyen 	u32			reg;
6220d36dedeSThinh Nguyen 	u8			speed;
623*614ce6a2SUdipto Goswami 	int			ret;
624138801aaSFelipe Balbi 
625138801aaSFelipe Balbi 	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
626138801aaSFelipe Balbi 		return -EFAULT;
627138801aaSFelipe Balbi 
628138801aaSFelipe Balbi 	if (!strncmp(buf, "SS.Disabled", 11))
629138801aaSFelipe Balbi 		state = DWC3_LINK_STATE_SS_DIS;
630138801aaSFelipe Balbi 	else if (!strncmp(buf, "Rx.Detect", 9))
631138801aaSFelipe Balbi 		state = DWC3_LINK_STATE_RX_DET;
632138801aaSFelipe Balbi 	else if (!strncmp(buf, "SS.Inactive", 11))
633138801aaSFelipe Balbi 		state = DWC3_LINK_STATE_SS_INACT;
634138801aaSFelipe Balbi 	else if (!strncmp(buf, "Recovery", 8))
635138801aaSFelipe Balbi 		state = DWC3_LINK_STATE_RECOV;
636138801aaSFelipe Balbi 	else if (!strncmp(buf, "Compliance", 10))
637138801aaSFelipe Balbi 		state = DWC3_LINK_STATE_CMPLY;
638138801aaSFelipe Balbi 	else if (!strncmp(buf, "Loopback", 8))
639138801aaSFelipe Balbi 		state = DWC3_LINK_STATE_LPBK;
640138801aaSFelipe Balbi 	else
641138801aaSFelipe Balbi 		return -EINVAL;
642138801aaSFelipe Balbi 
643*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
644*614ce6a2SUdipto Goswami 	if (ret < 0)
645*614ce6a2SUdipto Goswami 		return ret;
646*614ce6a2SUdipto Goswami 
647138801aaSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
648d102444cSThinh Nguyen 	reg = dwc3_readl(dwc->regs, DWC3_GSTS);
649d102444cSThinh Nguyen 	if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
650d102444cSThinh Nguyen 		spin_unlock_irqrestore(&dwc->lock, flags);
651*614ce6a2SUdipto Goswami 		pm_runtime_put_sync(dwc->dev);
652d102444cSThinh Nguyen 		return -EINVAL;
653d102444cSThinh Nguyen 	}
654d102444cSThinh Nguyen 
6550d36dedeSThinh Nguyen 	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
6560d36dedeSThinh Nguyen 	speed = reg & DWC3_DSTS_CONNECTSPD;
6570d36dedeSThinh Nguyen 
6580d36dedeSThinh Nguyen 	if (speed < DWC3_DSTS_SUPERSPEED &&
6590d36dedeSThinh Nguyen 	    state != DWC3_LINK_STATE_RECOV) {
6600d36dedeSThinh Nguyen 		spin_unlock_irqrestore(&dwc->lock, flags);
661*614ce6a2SUdipto Goswami 		pm_runtime_put_sync(dwc->dev);
6620d36dedeSThinh Nguyen 		return -EINVAL;
6630d36dedeSThinh Nguyen 	}
6640d36dedeSThinh Nguyen 
665138801aaSFelipe Balbi 	dwc3_gadget_set_link_state(dwc, state);
666138801aaSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
667138801aaSFelipe Balbi 
668*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
669*614ce6a2SUdipto Goswami 
670138801aaSFelipe Balbi 	return count;
671138801aaSFelipe Balbi }
672138801aaSFelipe Balbi 
673138801aaSFelipe Balbi static const struct file_operations dwc3_link_state_fops = {
674138801aaSFelipe Balbi 	.open			= dwc3_link_state_open,
675138801aaSFelipe Balbi 	.write			= dwc3_link_state_write,
676138801aaSFelipe Balbi 	.read			= seq_read,
677138801aaSFelipe Balbi 	.llseek			= seq_lseek,
678138801aaSFelipe Balbi 	.release		= single_release,
679138801aaSFelipe Balbi };
680138801aaSFelipe Balbi 
681818ec3abSFelipe Balbi struct dwc3_ep_file_map {
6826d5b53c1SFelipe Balbi 	const char name[25];
6836d5b53c1SFelipe Balbi 	const struct file_operations *const fops;
684818ec3abSFelipe Balbi };
685818ec3abSFelipe Balbi 
dwc3_tx_fifo_size_show(struct seq_file * s,void * unused)6862c85a181SThinh Nguyen static int dwc3_tx_fifo_size_show(struct seq_file *s, void *unused)
687818ec3abSFelipe Balbi {
688818ec3abSFelipe Balbi 	struct dwc3_ep		*dep = s->private;
689818ec3abSFelipe Balbi 	struct dwc3		*dwc = dep->dwc;
690818ec3abSFelipe Balbi 	unsigned long		flags;
691d00be779SThinh Nguyen 	u32			mdwidth;
692818ec3abSFelipe Balbi 	u32			val;
693*614ce6a2SUdipto Goswami 	int			ret;
694*614ce6a2SUdipto Goswami 
695*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
696*614ce6a2SUdipto Goswami 	if (ret < 0)
697*614ce6a2SUdipto Goswami 		return ret;
698818ec3abSFelipe Balbi 
699818ec3abSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
7002c85a181SThinh Nguyen 	val = dwc3_core_fifo_space(dep, DWC3_TXFIFO);
7010f874f79SThinh Nguyen 
7020f874f79SThinh Nguyen 	/* Convert to bytes */
703d00be779SThinh Nguyen 	mdwidth = dwc3_mdwidth(dwc);
7044244ba02SThinh Nguyen 
7054244ba02SThinh Nguyen 	val *= mdwidth;
7060f874f79SThinh Nguyen 	val >>= 3;
707818ec3abSFelipe Balbi 	seq_printf(s, "%u\n", val);
708818ec3abSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
709818ec3abSFelipe Balbi 
710*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
711*614ce6a2SUdipto Goswami 
712818ec3abSFelipe Balbi 	return 0;
713818ec3abSFelipe Balbi }
714818ec3abSFelipe Balbi 
dwc3_rx_fifo_size_show(struct seq_file * s,void * unused)7152c85a181SThinh Nguyen static int dwc3_rx_fifo_size_show(struct seq_file *s, void *unused)
716818ec3abSFelipe Balbi {
717818ec3abSFelipe Balbi 	struct dwc3_ep		*dep = s->private;
718818ec3abSFelipe Balbi 	struct dwc3		*dwc = dep->dwc;
719818ec3abSFelipe Balbi 	unsigned long		flags;
720d00be779SThinh Nguyen 	u32			mdwidth;
721818ec3abSFelipe Balbi 	u32			val;
722*614ce6a2SUdipto Goswami 	int			ret;
723*614ce6a2SUdipto Goswami 
724*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
725*614ce6a2SUdipto Goswami 	if (ret < 0)
726*614ce6a2SUdipto Goswami 		return ret;
727818ec3abSFelipe Balbi 
728818ec3abSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
7292c85a181SThinh Nguyen 	val = dwc3_core_fifo_space(dep, DWC3_RXFIFO);
7300f874f79SThinh Nguyen 
7310f874f79SThinh Nguyen 	/* Convert to bytes */
732d00be779SThinh Nguyen 	mdwidth = dwc3_mdwidth(dwc);
7334244ba02SThinh Nguyen 
7344244ba02SThinh Nguyen 	val *= mdwidth;
7350f874f79SThinh Nguyen 	val >>= 3;
736818ec3abSFelipe Balbi 	seq_printf(s, "%u\n", val);
737818ec3abSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
738818ec3abSFelipe Balbi 
739*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
740*614ce6a2SUdipto Goswami 
741818ec3abSFelipe Balbi 	return 0;
742818ec3abSFelipe Balbi }
743818ec3abSFelipe Balbi 
dwc3_tx_request_queue_show(struct seq_file * s,void * unused)744818ec3abSFelipe Balbi static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused)
745818ec3abSFelipe Balbi {
746818ec3abSFelipe Balbi 	struct dwc3_ep		*dep = s->private;
747818ec3abSFelipe Balbi 	struct dwc3		*dwc = dep->dwc;
748818ec3abSFelipe Balbi 	unsigned long		flags;
749818ec3abSFelipe Balbi 	u32			val;
750*614ce6a2SUdipto Goswami 	int			ret;
751*614ce6a2SUdipto Goswami 
752*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
753*614ce6a2SUdipto Goswami 	if (ret < 0)
754*614ce6a2SUdipto Goswami 		return ret;
755818ec3abSFelipe Balbi 
756818ec3abSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
757818ec3abSFelipe Balbi 	val = dwc3_core_fifo_space(dep, DWC3_TXREQQ);
758818ec3abSFelipe Balbi 	seq_printf(s, "%u\n", val);
759818ec3abSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
760818ec3abSFelipe Balbi 
761*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
762*614ce6a2SUdipto Goswami 
763818ec3abSFelipe Balbi 	return 0;
764818ec3abSFelipe Balbi }
765818ec3abSFelipe Balbi 
dwc3_rx_request_queue_show(struct seq_file * s,void * unused)766818ec3abSFelipe Balbi static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused)
767818ec3abSFelipe Balbi {
768818ec3abSFelipe Balbi 	struct dwc3_ep		*dep = s->private;
769818ec3abSFelipe Balbi 	struct dwc3		*dwc = dep->dwc;
770818ec3abSFelipe Balbi 	unsigned long		flags;
771818ec3abSFelipe Balbi 	u32			val;
772*614ce6a2SUdipto Goswami 	int			ret;
773*614ce6a2SUdipto Goswami 
774*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
775*614ce6a2SUdipto Goswami 	if (ret < 0)
776*614ce6a2SUdipto Goswami 		return ret;
777818ec3abSFelipe Balbi 
778818ec3abSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
779818ec3abSFelipe Balbi 	val = dwc3_core_fifo_space(dep, DWC3_RXREQQ);
780818ec3abSFelipe Balbi 	seq_printf(s, "%u\n", val);
781818ec3abSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
782818ec3abSFelipe Balbi 
783*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
784*614ce6a2SUdipto Goswami 
785818ec3abSFelipe Balbi 	return 0;
786818ec3abSFelipe Balbi }
787818ec3abSFelipe Balbi 
dwc3_rx_info_queue_show(struct seq_file * s,void * unused)788818ec3abSFelipe Balbi static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused)
789818ec3abSFelipe Balbi {
790818ec3abSFelipe Balbi 	struct dwc3_ep		*dep = s->private;
791818ec3abSFelipe Balbi 	struct dwc3		*dwc = dep->dwc;
792818ec3abSFelipe Balbi 	unsigned long		flags;
793818ec3abSFelipe Balbi 	u32			val;
794*614ce6a2SUdipto Goswami 	int			ret;
795*614ce6a2SUdipto Goswami 
796*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
797*614ce6a2SUdipto Goswami 	if (ret < 0)
798*614ce6a2SUdipto Goswami 		return ret;
799818ec3abSFelipe Balbi 
800818ec3abSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
801818ec3abSFelipe Balbi 	val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ);
802818ec3abSFelipe Balbi 	seq_printf(s, "%u\n", val);
803818ec3abSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
804818ec3abSFelipe Balbi 
805*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
806*614ce6a2SUdipto Goswami 
807818ec3abSFelipe Balbi 	return 0;
808818ec3abSFelipe Balbi }
809818ec3abSFelipe Balbi 
dwc3_descriptor_fetch_queue_show(struct seq_file * s,void * unused)810818ec3abSFelipe Balbi static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused)
811818ec3abSFelipe Balbi {
812818ec3abSFelipe Balbi 	struct dwc3_ep		*dep = s->private;
813818ec3abSFelipe Balbi 	struct dwc3		*dwc = dep->dwc;
814818ec3abSFelipe Balbi 	unsigned long		flags;
815818ec3abSFelipe Balbi 	u32			val;
816*614ce6a2SUdipto Goswami 	int			ret;
817*614ce6a2SUdipto Goswami 
818*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
819*614ce6a2SUdipto Goswami 	if (ret < 0)
820*614ce6a2SUdipto Goswami 		return ret;
821818ec3abSFelipe Balbi 
822818ec3abSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
823818ec3abSFelipe Balbi 	val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ);
824818ec3abSFelipe Balbi 	seq_printf(s, "%u\n", val);
825818ec3abSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
826818ec3abSFelipe Balbi 
827*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
828*614ce6a2SUdipto Goswami 
829818ec3abSFelipe Balbi 	return 0;
830818ec3abSFelipe Balbi }
831818ec3abSFelipe Balbi 
dwc3_event_queue_show(struct seq_file * s,void * unused)832818ec3abSFelipe Balbi static int dwc3_event_queue_show(struct seq_file *s, void *unused)
833818ec3abSFelipe Balbi {
834818ec3abSFelipe Balbi 	struct dwc3_ep		*dep = s->private;
835818ec3abSFelipe Balbi 	struct dwc3		*dwc = dep->dwc;
836818ec3abSFelipe Balbi 	unsigned long		flags;
837818ec3abSFelipe Balbi 	u32			val;
838*614ce6a2SUdipto Goswami 	int			ret;
839*614ce6a2SUdipto Goswami 
840*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
841*614ce6a2SUdipto Goswami 	if (ret < 0)
842*614ce6a2SUdipto Goswami 		return ret;
843818ec3abSFelipe Balbi 
844818ec3abSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
845818ec3abSFelipe Balbi 	val = dwc3_core_fifo_space(dep, DWC3_EVENTQ);
846818ec3abSFelipe Balbi 	seq_printf(s, "%u\n", val);
847818ec3abSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
848818ec3abSFelipe Balbi 
849*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
850*614ce6a2SUdipto Goswami 
851818ec3abSFelipe Balbi 	return 0;
852818ec3abSFelipe Balbi }
853818ec3abSFelipe Balbi 
dwc3_transfer_type_show(struct seq_file * s,void * unused)8546d5b53c1SFelipe Balbi static int dwc3_transfer_type_show(struct seq_file *s, void *unused)
855818ec3abSFelipe Balbi {
856818ec3abSFelipe Balbi 	struct dwc3_ep		*dep = s->private;
857818ec3abSFelipe Balbi 	struct dwc3		*dwc = dep->dwc;
858818ec3abSFelipe Balbi 	unsigned long		flags;
859818ec3abSFelipe Balbi 
860818ec3abSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
8619ae0eb45SFelipe Balbi 	if (!(dep->flags & DWC3_EP_ENABLED) || !dep->endpoint.desc) {
8629ae0eb45SFelipe Balbi 		seq_puts(s, "--\n");
863818ec3abSFelipe Balbi 		goto out;
864818ec3abSFelipe Balbi 	}
865818ec3abSFelipe Balbi 
866818ec3abSFelipe Balbi 	switch (usb_endpoint_type(dep->endpoint.desc)) {
867818ec3abSFelipe Balbi 	case USB_ENDPOINT_XFER_CONTROL:
8689ae0eb45SFelipe Balbi 		seq_puts(s, "control\n");
869818ec3abSFelipe Balbi 		break;
870818ec3abSFelipe Balbi 	case USB_ENDPOINT_XFER_ISOC:
8719ae0eb45SFelipe Balbi 		seq_puts(s, "isochronous\n");
872818ec3abSFelipe Balbi 		break;
873818ec3abSFelipe Balbi 	case USB_ENDPOINT_XFER_BULK:
8749ae0eb45SFelipe Balbi 		seq_puts(s, "bulk\n");
875818ec3abSFelipe Balbi 		break;
876818ec3abSFelipe Balbi 	case USB_ENDPOINT_XFER_INT:
8779ae0eb45SFelipe Balbi 		seq_puts(s, "interrupt\n");
878818ec3abSFelipe Balbi 		break;
879818ec3abSFelipe Balbi 	default:
8809ae0eb45SFelipe Balbi 		seq_puts(s, "--\n");
881818ec3abSFelipe Balbi 	}
882818ec3abSFelipe Balbi 
883818ec3abSFelipe Balbi out:
884818ec3abSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
885818ec3abSFelipe Balbi 
886818ec3abSFelipe Balbi 	return 0;
887818ec3abSFelipe Balbi }
888818ec3abSFelipe Balbi 
dwc3_trb_ring_show(struct seq_file * s,void * unused)8896d5b53c1SFelipe Balbi static int dwc3_trb_ring_show(struct seq_file *s, void *unused)
890818ec3abSFelipe Balbi {
891818ec3abSFelipe Balbi 	struct dwc3_ep		*dep = s->private;
892818ec3abSFelipe Balbi 	struct dwc3		*dwc = dep->dwc;
893818ec3abSFelipe Balbi 	unsigned long		flags;
894818ec3abSFelipe Balbi 	int			i;
895*614ce6a2SUdipto Goswami 	int			ret;
896*614ce6a2SUdipto Goswami 
897*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
898*614ce6a2SUdipto Goswami 	if (ret < 0)
899*614ce6a2SUdipto Goswami 		return ret;
900818ec3abSFelipe Balbi 
901818ec3abSFelipe Balbi 	spin_lock_irqsave(&dwc->lock, flags);
902818ec3abSFelipe Balbi 	if (dep->number <= 1) {
9039ae0eb45SFelipe Balbi 		seq_puts(s, "--\n");
904818ec3abSFelipe Balbi 		goto out;
905818ec3abSFelipe Balbi 	}
906818ec3abSFelipe Balbi 
9079ae0eb45SFelipe Balbi 	seq_puts(s, "buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo\n");
908818ec3abSFelipe Balbi 
909818ec3abSFelipe Balbi 	for (i = 0; i < DWC3_TRB_NUM; i++) {
910818ec3abSFelipe Balbi 		struct dwc3_trb *trb = &dep->trb_pool[i];
911b5c7ed5cSFelipe Balbi 		unsigned int type = DWC3_TRBCTL_TYPE(trb->ctrl);
912818ec3abSFelipe Balbi 
913436841d5SFelipe Balbi 		seq_printf(s, "%08x%08x,%d,%s,%d,%d,%d,%d,%d,%d       %c%c\n",
914818ec3abSFelipe Balbi 				trb->bph, trb->bpl, trb->size,
915b5c7ed5cSFelipe Balbi 				dwc3_trb_type_string(type),
916818ec3abSFelipe Balbi 				!!(trb->ctrl & DWC3_TRB_CTRL_IOC),
917818ec3abSFelipe Balbi 				!!(trb->ctrl & DWC3_TRB_CTRL_ISP_IMI),
918818ec3abSFelipe Balbi 				!!(trb->ctrl & DWC3_TRB_CTRL_CSP),
919818ec3abSFelipe Balbi 				!!(trb->ctrl & DWC3_TRB_CTRL_CHN),
920818ec3abSFelipe Balbi 				!!(trb->ctrl & DWC3_TRB_CTRL_LST),
921436841d5SFelipe Balbi 				!!(trb->ctrl & DWC3_TRB_CTRL_HWO),
922436841d5SFelipe Balbi 				dep->trb_enqueue == i ? 'E' : ' ',
923436841d5SFelipe Balbi 				dep->trb_dequeue == i ? 'D' : ' ');
924818ec3abSFelipe Balbi 	}
925818ec3abSFelipe Balbi 
926818ec3abSFelipe Balbi out:
927818ec3abSFelipe Balbi 	spin_unlock_irqrestore(&dwc->lock, flags);
928818ec3abSFelipe Balbi 
929*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
930*614ce6a2SUdipto Goswami 
931818ec3abSFelipe Balbi 	return 0;
932818ec3abSFelipe Balbi }
933818ec3abSFelipe Balbi 
dwc3_ep_info_register_show(struct seq_file * s,void * unused)93462ba09d6SThinh Nguyen static int dwc3_ep_info_register_show(struct seq_file *s, void *unused)
93562ba09d6SThinh Nguyen {
93662ba09d6SThinh Nguyen 	struct dwc3_ep		*dep = s->private;
93762ba09d6SThinh Nguyen 	struct dwc3		*dwc = dep->dwc;
93862ba09d6SThinh Nguyen 	unsigned long		flags;
93962ba09d6SThinh Nguyen 	u64			ep_info;
94062ba09d6SThinh Nguyen 	u32			lower_32_bits;
94162ba09d6SThinh Nguyen 	u32			upper_32_bits;
94262ba09d6SThinh Nguyen 	u32			reg;
943*614ce6a2SUdipto Goswami 	int			ret;
944*614ce6a2SUdipto Goswami 
945*614ce6a2SUdipto Goswami 	ret = pm_runtime_resume_and_get(dwc->dev);
946*614ce6a2SUdipto Goswami 	if (ret < 0)
947*614ce6a2SUdipto Goswami 		return ret;
94862ba09d6SThinh Nguyen 
94962ba09d6SThinh Nguyen 	spin_lock_irqsave(&dwc->lock, flags);
95062ba09d6SThinh Nguyen 	reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number);
95162ba09d6SThinh Nguyen 	dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
95262ba09d6SThinh Nguyen 
95362ba09d6SThinh Nguyen 	lower_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO0);
95462ba09d6SThinh Nguyen 	upper_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO1);
95562ba09d6SThinh Nguyen 
95662ba09d6SThinh Nguyen 	ep_info = ((u64)upper_32_bits << 32) | lower_32_bits;
95762ba09d6SThinh Nguyen 	seq_printf(s, "0x%016llx\n", ep_info);
95862ba09d6SThinh Nguyen 	spin_unlock_irqrestore(&dwc->lock, flags);
95962ba09d6SThinh Nguyen 
960*614ce6a2SUdipto Goswami 	pm_runtime_put_sync(dwc->dev);
961*614ce6a2SUdipto Goswami 
96262ba09d6SThinh Nguyen 	return 0;
96362ba09d6SThinh Nguyen }
96462ba09d6SThinh Nguyen 
9652c85a181SThinh Nguyen DEFINE_SHOW_ATTRIBUTE(dwc3_tx_fifo_size);
9662c85a181SThinh Nguyen DEFINE_SHOW_ATTRIBUTE(dwc3_rx_fifo_size);
9676d5b53c1SFelipe Balbi DEFINE_SHOW_ATTRIBUTE(dwc3_tx_request_queue);
9686d5b53c1SFelipe Balbi DEFINE_SHOW_ATTRIBUTE(dwc3_rx_request_queue);
9696d5b53c1SFelipe Balbi DEFINE_SHOW_ATTRIBUTE(dwc3_rx_info_queue);
9706d5b53c1SFelipe Balbi DEFINE_SHOW_ATTRIBUTE(dwc3_descriptor_fetch_queue);
9716d5b53c1SFelipe Balbi DEFINE_SHOW_ATTRIBUTE(dwc3_event_queue);
9726d5b53c1SFelipe Balbi DEFINE_SHOW_ATTRIBUTE(dwc3_transfer_type);
9736d5b53c1SFelipe Balbi DEFINE_SHOW_ATTRIBUTE(dwc3_trb_ring);
97462ba09d6SThinh Nguyen DEFINE_SHOW_ATTRIBUTE(dwc3_ep_info_register);
9756d5b53c1SFelipe Balbi 
9766d5b53c1SFelipe Balbi static const struct dwc3_ep_file_map dwc3_ep_file_map[] = {
9772c85a181SThinh Nguyen 	{ "tx_fifo_size", &dwc3_tx_fifo_size_fops, },
9782c85a181SThinh Nguyen 	{ "rx_fifo_size", &dwc3_rx_fifo_size_fops, },
9796d5b53c1SFelipe Balbi 	{ "tx_request_queue", &dwc3_tx_request_queue_fops, },
9806d5b53c1SFelipe Balbi 	{ "rx_request_queue", &dwc3_rx_request_queue_fops, },
9816d5b53c1SFelipe Balbi 	{ "rx_info_queue", &dwc3_rx_info_queue_fops, },
9826d5b53c1SFelipe Balbi 	{ "descriptor_fetch_queue", &dwc3_descriptor_fetch_queue_fops, },
9836d5b53c1SFelipe Balbi 	{ "event_queue", &dwc3_event_queue_fops, },
9846d5b53c1SFelipe Balbi 	{ "transfer_type", &dwc3_transfer_type_fops, },
9856d5b53c1SFelipe Balbi 	{ "trb_ring", &dwc3_trb_ring_fops, },
98662ba09d6SThinh Nguyen 	{ "GDBGEPINFO", &dwc3_ep_info_register_fops, },
987818ec3abSFelipe Balbi };
988818ec3abSFelipe Balbi 
dwc3_debugfs_create_endpoint_dir(struct dwc3_ep * dep)989be308d68SGreg Kroah-Hartman void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep)
990818ec3abSFelipe Balbi {
991be308d68SGreg Kroah-Hartman 	struct dentry		*dir;
992818ec3abSFelipe Balbi 	int			i;
993818ec3abSFelipe Balbi 
994be308d68SGreg Kroah-Hartman 	dir = debugfs_create_dir(dep->name, dep->dwc->debug_root);
9956d5b53c1SFelipe Balbi 	for (i = 0; i < ARRAY_SIZE(dwc3_ep_file_map); i++) {
9966d5b53c1SFelipe Balbi 		const struct file_operations *fops = dwc3_ep_file_map[i].fops;
9976d5b53c1SFelipe Balbi 		const char *name = dwc3_ep_file_map[i].name;
9986d5b53c1SFelipe Balbi 
999be308d68SGreg Kroah-Hartman 		debugfs_create_file(name, 0444, dir, dep, fops);
10006d5b53c1SFelipe Balbi 	}
1001818ec3abSFelipe Balbi }
1002818ec3abSFelipe Balbi 
dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep * dep)1003be308d68SGreg Kroah-Hartman void dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep *dep)
1004818ec3abSFelipe Balbi {
1005be308d68SGreg Kroah-Hartman 	debugfs_lookup_and_remove(dep->name, dep->dwc->debug_root);
1006818ec3abSFelipe Balbi }
1007818ec3abSFelipe Balbi 
dwc3_debugfs_init(struct dwc3 * dwc)10084e9f3118SDu, Changbin void dwc3_debugfs_init(struct dwc3 *dwc)
100972246da4SFelipe Balbi {
101072246da4SFelipe Balbi 	struct dentry		*root;
101172246da4SFelipe Balbi 
1012d7668024SFelipe Balbi 	dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL);
1013535c8dc5SGreg Kroah-Hartman 	if (!dwc->regset)
10144e9f3118SDu, Changbin 		return;
1015d7668024SFelipe Balbi 
101662ba09d6SThinh Nguyen 	dwc->dbg_lsp_select = DWC3_LSP_MUX_UNSELECTED;
101762ba09d6SThinh Nguyen 
1018d7668024SFelipe Balbi 	dwc->regset->regs = dwc3_regs;
1019d7668024SFelipe Balbi 	dwc->regset->nregs = ARRAY_SIZE(dwc3_regs);
10202eb88016SFelipe Balbi 	dwc->regset->base = dwc->regs - DWC3_GLOBALS_REGS_START;
1021*614ce6a2SUdipto Goswami 	dwc->regset->dev = dwc->dev;
1022d7668024SFelipe Balbi 
1023dcf5a2c3SChunfeng Yun 	root = debugfs_create_dir(dev_name(dwc->dev), usb_debug_root);
1024be308d68SGreg Kroah-Hartman 	dwc->debug_root = root;
10259ae0eb45SFelipe Balbi 	debugfs_create_regset32("regdump", 0444, root, dwc->regset);
10269ae0eb45SFelipe Balbi 	debugfs_create_file("lsp_dump", 0644, root, dwc, &dwc3_lsp_fops);
10270b9fe32dSFelipe Balbi 
10289ae0eb45SFelipe Balbi 	if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE))
10299ae0eb45SFelipe Balbi 		debugfs_create_file("mode", 0644, root, dwc,
1030535c8dc5SGreg Kroah-Hartman 				    &dwc3_mode_fops);
10310b9fe32dSFelipe Balbi 
1032dbfff05dSFelipe Balbi 	if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) ||
1033dbfff05dSFelipe Balbi 			IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
10349ae0eb45SFelipe Balbi 		debugfs_create_file("testmode", 0644, root, dwc,
1035535c8dc5SGreg Kroah-Hartman 				&dwc3_testmode_fops);
10369ae0eb45SFelipe Balbi 		debugfs_create_file("link_state", 0644, root, dwc,
1037535c8dc5SGreg Kroah-Hartman 				    &dwc3_link_state_fops);
1038080d921fSFelipe Balbi 	}
103972246da4SFelipe Balbi }
104072246da4SFelipe Balbi 
dwc3_debugfs_exit(struct dwc3 * dwc)1041fb4e98abSBill Pemberton void dwc3_debugfs_exit(struct dwc3 *dwc)
104272246da4SFelipe Balbi {
1043be308d68SGreg Kroah-Hartman 	debugfs_lookup_and_remove(dev_name(dwc->dev), usb_debug_root);
1044e6bdf819SDu, Changbin 	kfree(dwc->regset);
104572246da4SFelipe Balbi }
1046