cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

debugfs.c (23715B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * debugfs.c - DesignWare USB3 DRD Controller DebugFS file
      4 *
      5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
      6 *
      7 * Authors: Felipe Balbi <balbi@ti.com>,
      8 *	    Sebastian Andrzej Siewior <bigeasy@linutronix.de>
      9 */
     10
     11#include <linux/kernel.h>
     12#include <linux/slab.h>
     13#include <linux/ptrace.h>
     14#include <linux/types.h>
     15#include <linux/spinlock.h>
     16#include <linux/debugfs.h>
     17#include <linux/seq_file.h>
     18#include <linux/delay.h>
     19#include <linux/uaccess.h>
     20
     21#include <linux/usb/ch9.h>
     22
     23#include "core.h"
     24#include "gadget.h"
     25#include "io.h"
     26#include "debug.h"
     27
     28#define DWC3_LSP_MUX_UNSELECTED 0xfffff
     29
     30#define dump_register(nm)				\
     31{							\
     32	.name	= __stringify(nm),			\
     33	.offset	= DWC3_ ##nm,				\
     34}
     35
     36#define dump_ep_register_set(n)			\
     37	{					\
     38		.name = "DEPCMDPAR2("__stringify(n)")",	\
     39		.offset = DWC3_DEP_BASE(n) +	\
     40			DWC3_DEPCMDPAR2,	\
     41	},					\
     42	{					\
     43		.name = "DEPCMDPAR1("__stringify(n)")",	\
     44		.offset = DWC3_DEP_BASE(n) +	\
     45			DWC3_DEPCMDPAR1,	\
     46	},					\
     47	{					\
     48		.name = "DEPCMDPAR0("__stringify(n)")",	\
     49		.offset = DWC3_DEP_BASE(n) +	\
     50			DWC3_DEPCMDPAR0,	\
     51	},					\
     52	{					\
     53		.name = "DEPCMD("__stringify(n)")",	\
     54		.offset = DWC3_DEP_BASE(n) +	\
     55			DWC3_DEPCMD,		\
     56	}
     57
     58
     59static const struct debugfs_reg32 dwc3_regs[] = {
     60	dump_register(GSBUSCFG0),
     61	dump_register(GSBUSCFG1),
     62	dump_register(GTXTHRCFG),
     63	dump_register(GRXTHRCFG),
     64	dump_register(GCTL),
     65	dump_register(GEVTEN),
     66	dump_register(GSTS),
     67	dump_register(GUCTL1),
     68	dump_register(GSNPSID),
     69	dump_register(GGPIO),
     70	dump_register(GUID),
     71	dump_register(GUCTL),
     72	dump_register(GBUSERRADDR0),
     73	dump_register(GBUSERRADDR1),
     74	dump_register(GPRTBIMAP0),
     75	dump_register(GPRTBIMAP1),
     76	dump_register(GHWPARAMS0),
     77	dump_register(GHWPARAMS1),
     78	dump_register(GHWPARAMS2),
     79	dump_register(GHWPARAMS3),
     80	dump_register(GHWPARAMS4),
     81	dump_register(GHWPARAMS5),
     82	dump_register(GHWPARAMS6),
     83	dump_register(GHWPARAMS7),
     84	dump_register(GDBGFIFOSPACE),
     85	dump_register(GDBGLTSSM),
     86	dump_register(GDBGBMU),
     87	dump_register(GPRTBIMAP_HS0),
     88	dump_register(GPRTBIMAP_HS1),
     89	dump_register(GPRTBIMAP_FS0),
     90	dump_register(GPRTBIMAP_FS1),
     91
     92	dump_register(GUSB2PHYCFG(0)),
     93	dump_register(GUSB2PHYCFG(1)),
     94	dump_register(GUSB2PHYCFG(2)),
     95	dump_register(GUSB2PHYCFG(3)),
     96	dump_register(GUSB2PHYCFG(4)),
     97	dump_register(GUSB2PHYCFG(5)),
     98	dump_register(GUSB2PHYCFG(6)),
     99	dump_register(GUSB2PHYCFG(7)),
    100	dump_register(GUSB2PHYCFG(8)),
    101	dump_register(GUSB2PHYCFG(9)),
    102	dump_register(GUSB2PHYCFG(10)),
    103	dump_register(GUSB2PHYCFG(11)),
    104	dump_register(GUSB2PHYCFG(12)),
    105	dump_register(GUSB2PHYCFG(13)),
    106	dump_register(GUSB2PHYCFG(14)),
    107	dump_register(GUSB2PHYCFG(15)),
    108
    109	dump_register(GUSB2I2CCTL(0)),
    110	dump_register(GUSB2I2CCTL(1)),
    111	dump_register(GUSB2I2CCTL(2)),
    112	dump_register(GUSB2I2CCTL(3)),
    113	dump_register(GUSB2I2CCTL(4)),
    114	dump_register(GUSB2I2CCTL(5)),
    115	dump_register(GUSB2I2CCTL(6)),
    116	dump_register(GUSB2I2CCTL(7)),
    117	dump_register(GUSB2I2CCTL(8)),
    118	dump_register(GUSB2I2CCTL(9)),
    119	dump_register(GUSB2I2CCTL(10)),
    120	dump_register(GUSB2I2CCTL(11)),
    121	dump_register(GUSB2I2CCTL(12)),
    122	dump_register(GUSB2I2CCTL(13)),
    123	dump_register(GUSB2I2CCTL(14)),
    124	dump_register(GUSB2I2CCTL(15)),
    125
    126	dump_register(GUSB2PHYACC(0)),
    127	dump_register(GUSB2PHYACC(1)),
    128	dump_register(GUSB2PHYACC(2)),
    129	dump_register(GUSB2PHYACC(3)),
    130	dump_register(GUSB2PHYACC(4)),
    131	dump_register(GUSB2PHYACC(5)),
    132	dump_register(GUSB2PHYACC(6)),
    133	dump_register(GUSB2PHYACC(7)),
    134	dump_register(GUSB2PHYACC(8)),
    135	dump_register(GUSB2PHYACC(9)),
    136	dump_register(GUSB2PHYACC(10)),
    137	dump_register(GUSB2PHYACC(11)),
    138	dump_register(GUSB2PHYACC(12)),
    139	dump_register(GUSB2PHYACC(13)),
    140	dump_register(GUSB2PHYACC(14)),
    141	dump_register(GUSB2PHYACC(15)),
    142
    143	dump_register(GUSB3PIPECTL(0)),
    144	dump_register(GUSB3PIPECTL(1)),
    145	dump_register(GUSB3PIPECTL(2)),
    146	dump_register(GUSB3PIPECTL(3)),
    147	dump_register(GUSB3PIPECTL(4)),
    148	dump_register(GUSB3PIPECTL(5)),
    149	dump_register(GUSB3PIPECTL(6)),
    150	dump_register(GUSB3PIPECTL(7)),
    151	dump_register(GUSB3PIPECTL(8)),
    152	dump_register(GUSB3PIPECTL(9)),
    153	dump_register(GUSB3PIPECTL(10)),
    154	dump_register(GUSB3PIPECTL(11)),
    155	dump_register(GUSB3PIPECTL(12)),
    156	dump_register(GUSB3PIPECTL(13)),
    157	dump_register(GUSB3PIPECTL(14)),
    158	dump_register(GUSB3PIPECTL(15)),
    159
    160	dump_register(GTXFIFOSIZ(0)),
    161	dump_register(GTXFIFOSIZ(1)),
    162	dump_register(GTXFIFOSIZ(2)),
    163	dump_register(GTXFIFOSIZ(3)),
    164	dump_register(GTXFIFOSIZ(4)),
    165	dump_register(GTXFIFOSIZ(5)),
    166	dump_register(GTXFIFOSIZ(6)),
    167	dump_register(GTXFIFOSIZ(7)),
    168	dump_register(GTXFIFOSIZ(8)),
    169	dump_register(GTXFIFOSIZ(9)),
    170	dump_register(GTXFIFOSIZ(10)),
    171	dump_register(GTXFIFOSIZ(11)),
    172	dump_register(GTXFIFOSIZ(12)),
    173	dump_register(GTXFIFOSIZ(13)),
    174	dump_register(GTXFIFOSIZ(14)),
    175	dump_register(GTXFIFOSIZ(15)),
    176	dump_register(GTXFIFOSIZ(16)),
    177	dump_register(GTXFIFOSIZ(17)),
    178	dump_register(GTXFIFOSIZ(18)),
    179	dump_register(GTXFIFOSIZ(19)),
    180	dump_register(GTXFIFOSIZ(20)),
    181	dump_register(GTXFIFOSIZ(21)),
    182	dump_register(GTXFIFOSIZ(22)),
    183	dump_register(GTXFIFOSIZ(23)),
    184	dump_register(GTXFIFOSIZ(24)),
    185	dump_register(GTXFIFOSIZ(25)),
    186	dump_register(GTXFIFOSIZ(26)),
    187	dump_register(GTXFIFOSIZ(27)),
    188	dump_register(GTXFIFOSIZ(28)),
    189	dump_register(GTXFIFOSIZ(29)),
    190	dump_register(GTXFIFOSIZ(30)),
    191	dump_register(GTXFIFOSIZ(31)),
    192
    193	dump_register(GRXFIFOSIZ(0)),
    194	dump_register(GRXFIFOSIZ(1)),
    195	dump_register(GRXFIFOSIZ(2)),
    196	dump_register(GRXFIFOSIZ(3)),
    197	dump_register(GRXFIFOSIZ(4)),
    198	dump_register(GRXFIFOSIZ(5)),
    199	dump_register(GRXFIFOSIZ(6)),
    200	dump_register(GRXFIFOSIZ(7)),
    201	dump_register(GRXFIFOSIZ(8)),
    202	dump_register(GRXFIFOSIZ(9)),
    203	dump_register(GRXFIFOSIZ(10)),
    204	dump_register(GRXFIFOSIZ(11)),
    205	dump_register(GRXFIFOSIZ(12)),
    206	dump_register(GRXFIFOSIZ(13)),
    207	dump_register(GRXFIFOSIZ(14)),
    208	dump_register(GRXFIFOSIZ(15)),
    209	dump_register(GRXFIFOSIZ(16)),
    210	dump_register(GRXFIFOSIZ(17)),
    211	dump_register(GRXFIFOSIZ(18)),
    212	dump_register(GRXFIFOSIZ(19)),
    213	dump_register(GRXFIFOSIZ(20)),
    214	dump_register(GRXFIFOSIZ(21)),
    215	dump_register(GRXFIFOSIZ(22)),
    216	dump_register(GRXFIFOSIZ(23)),
    217	dump_register(GRXFIFOSIZ(24)),
    218	dump_register(GRXFIFOSIZ(25)),
    219	dump_register(GRXFIFOSIZ(26)),
    220	dump_register(GRXFIFOSIZ(27)),
    221	dump_register(GRXFIFOSIZ(28)),
    222	dump_register(GRXFIFOSIZ(29)),
    223	dump_register(GRXFIFOSIZ(30)),
    224	dump_register(GRXFIFOSIZ(31)),
    225
    226	dump_register(GEVNTADRLO(0)),
    227	dump_register(GEVNTADRHI(0)),
    228	dump_register(GEVNTSIZ(0)),
    229	dump_register(GEVNTCOUNT(0)),
    230
    231	dump_register(GHWPARAMS8),
    232	dump_register(DCFG),
    233	dump_register(DCTL),
    234	dump_register(DEVTEN),
    235	dump_register(DSTS),
    236	dump_register(DGCMDPAR),
    237	dump_register(DGCMD),
    238	dump_register(DALEPENA),
    239
    240	dump_ep_register_set(0),
    241	dump_ep_register_set(1),
    242	dump_ep_register_set(2),
    243	dump_ep_register_set(3),
    244	dump_ep_register_set(4),
    245	dump_ep_register_set(5),
    246	dump_ep_register_set(6),
    247	dump_ep_register_set(7),
    248	dump_ep_register_set(8),
    249	dump_ep_register_set(9),
    250	dump_ep_register_set(10),
    251	dump_ep_register_set(11),
    252	dump_ep_register_set(12),
    253	dump_ep_register_set(13),
    254	dump_ep_register_set(14),
    255	dump_ep_register_set(15),
    256	dump_ep_register_set(16),
    257	dump_ep_register_set(17),
    258	dump_ep_register_set(18),
    259	dump_ep_register_set(19),
    260	dump_ep_register_set(20),
    261	dump_ep_register_set(21),
    262	dump_ep_register_set(22),
    263	dump_ep_register_set(23),
    264	dump_ep_register_set(24),
    265	dump_ep_register_set(25),
    266	dump_ep_register_set(26),
    267	dump_ep_register_set(27),
    268	dump_ep_register_set(28),
    269	dump_ep_register_set(29),
    270	dump_ep_register_set(30),
    271	dump_ep_register_set(31),
    272
    273	dump_register(OCFG),
    274	dump_register(OCTL),
    275	dump_register(OEVT),
    276	dump_register(OEVTEN),
    277	dump_register(OSTS),
    278};
    279
    280static void dwc3_host_lsp(struct seq_file *s)
    281{
    282	struct dwc3		*dwc = s->private;
    283	bool			dbc_enabled;
    284	u32			sel;
    285	u32			reg;
    286	u32			val;
    287
    288	dbc_enabled = !!(dwc->hwparams.hwparams1 & DWC3_GHWPARAMS1_ENDBC);
    289
    290	sel = dwc->dbg_lsp_select;
    291	if (sel == DWC3_LSP_MUX_UNSELECTED) {
    292		seq_puts(s, "Write LSP selection to print for host\n");
    293		return;
    294	}
    295
    296	reg = DWC3_GDBGLSPMUX_HOSTSELECT(sel);
    297
    298	dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
    299	val = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
    300	seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", sel, val);
    301
    302	if (dbc_enabled && sel < 256) {
    303		reg |= DWC3_GDBGLSPMUX_ENDBC;
    304		dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
    305		val = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
    306		seq_printf(s, "GDBGLSP_DBC[%d] = 0x%08x\n", sel, val);
    307	}
    308}
    309
    310static void dwc3_gadget_lsp(struct seq_file *s)
    311{
    312	struct dwc3		*dwc = s->private;
    313	int			i;
    314	u32			reg;
    315
    316	for (i = 0; i < 16; i++) {
    317		reg = DWC3_GDBGLSPMUX_DEVSELECT(i);
    318		dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
    319		reg = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
    320		seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", i, reg);
    321	}
    322}
    323
    324static int dwc3_lsp_show(struct seq_file *s, void *unused)
    325{
    326	struct dwc3		*dwc = s->private;
    327	unsigned int		current_mode;
    328	unsigned long		flags;
    329	u32			reg;
    330
    331	spin_lock_irqsave(&dwc->lock, flags);
    332	reg = dwc3_readl(dwc->regs, DWC3_GSTS);
    333	current_mode = DWC3_GSTS_CURMOD(reg);
    334
    335	switch (current_mode) {
    336	case DWC3_GSTS_CURMOD_HOST:
    337		dwc3_host_lsp(s);
    338		break;
    339	case DWC3_GSTS_CURMOD_DEVICE:
    340		dwc3_gadget_lsp(s);
    341		break;
    342	default:
    343		seq_puts(s, "Mode is unknown, no LSP register printed\n");
    344		break;
    345	}
    346	spin_unlock_irqrestore(&dwc->lock, flags);
    347
    348	return 0;
    349}
    350
    351static int dwc3_lsp_open(struct inode *inode, struct file *file)
    352{
    353	return single_open(file, dwc3_lsp_show, inode->i_private);
    354}
    355
    356static ssize_t dwc3_lsp_write(struct file *file, const char __user *ubuf,
    357			      size_t count, loff_t *ppos)
    358{
    359	struct seq_file		*s = file->private_data;
    360	struct dwc3		*dwc = s->private;
    361	unsigned long		flags;
    362	char			buf[32] = { 0 };
    363	u32			sel;
    364	int			ret;
    365
    366	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
    367		return -EFAULT;
    368
    369	ret = kstrtouint(buf, 0, &sel);
    370	if (ret)
    371		return ret;
    372
    373	spin_lock_irqsave(&dwc->lock, flags);
    374	dwc->dbg_lsp_select = sel;
    375	spin_unlock_irqrestore(&dwc->lock, flags);
    376
    377	return count;
    378}
    379
    380static const struct file_operations dwc3_lsp_fops = {
    381	.open			= dwc3_lsp_open,
    382	.write			= dwc3_lsp_write,
    383	.read			= seq_read,
    384	.llseek			= seq_lseek,
    385	.release		= single_release,
    386};
    387
    388static int dwc3_mode_show(struct seq_file *s, void *unused)
    389{
    390	struct dwc3		*dwc = s->private;
    391	unsigned long		flags;
    392	u32			reg;
    393
    394	spin_lock_irqsave(&dwc->lock, flags);
    395	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
    396	spin_unlock_irqrestore(&dwc->lock, flags);
    397
    398	switch (DWC3_GCTL_PRTCAP(reg)) {
    399	case DWC3_GCTL_PRTCAP_HOST:
    400		seq_puts(s, "host\n");
    401		break;
    402	case DWC3_GCTL_PRTCAP_DEVICE:
    403		seq_puts(s, "device\n");
    404		break;
    405	case DWC3_GCTL_PRTCAP_OTG:
    406		seq_puts(s, "otg\n");
    407		break;
    408	default:
    409		seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg));
    410	}
    411
    412	return 0;
    413}
    414
    415static int dwc3_mode_open(struct inode *inode, struct file *file)
    416{
    417	return single_open(file, dwc3_mode_show, inode->i_private);
    418}
    419
    420static ssize_t dwc3_mode_write(struct file *file,
    421		const char __user *ubuf, size_t count, loff_t *ppos)
    422{
    423	struct seq_file		*s = file->private_data;
    424	struct dwc3		*dwc = s->private;
    425	u32			mode = 0;
    426	char			buf[32];
    427
    428	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
    429		return -EFAULT;
    430
    431	if (dwc->dr_mode != USB_DR_MODE_OTG)
    432		return count;
    433
    434	if (!strncmp(buf, "host", 4))
    435		mode = DWC3_GCTL_PRTCAP_HOST;
    436
    437	if (!strncmp(buf, "device", 6))
    438		mode = DWC3_GCTL_PRTCAP_DEVICE;
    439
    440	if (!strncmp(buf, "otg", 3))
    441		mode = DWC3_GCTL_PRTCAP_OTG;
    442
    443	dwc3_set_mode(dwc, mode);
    444
    445	return count;
    446}
    447
    448static const struct file_operations dwc3_mode_fops = {
    449	.open			= dwc3_mode_open,
    450	.write			= dwc3_mode_write,
    451	.read			= seq_read,
    452	.llseek			= seq_lseek,
    453	.release		= single_release,
    454};
    455
    456static int dwc3_testmode_show(struct seq_file *s, void *unused)
    457{
    458	struct dwc3		*dwc = s->private;
    459	unsigned long		flags;
    460	u32			reg;
    461
    462	spin_lock_irqsave(&dwc->lock, flags);
    463	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
    464	reg &= DWC3_DCTL_TSTCTRL_MASK;
    465	reg >>= 1;
    466	spin_unlock_irqrestore(&dwc->lock, flags);
    467
    468	switch (reg) {
    469	case 0:
    470		seq_puts(s, "no test\n");
    471		break;
    472	case USB_TEST_J:
    473		seq_puts(s, "test_j\n");
    474		break;
    475	case USB_TEST_K:
    476		seq_puts(s, "test_k\n");
    477		break;
    478	case USB_TEST_SE0_NAK:
    479		seq_puts(s, "test_se0_nak\n");
    480		break;
    481	case USB_TEST_PACKET:
    482		seq_puts(s, "test_packet\n");
    483		break;
    484	case USB_TEST_FORCE_ENABLE:
    485		seq_puts(s, "test_force_enable\n");
    486		break;
    487	default:
    488		seq_printf(s, "UNKNOWN %d\n", reg);
    489	}
    490
    491	return 0;
    492}
    493
    494static int dwc3_testmode_open(struct inode *inode, struct file *file)
    495{
    496	return single_open(file, dwc3_testmode_show, inode->i_private);
    497}
    498
    499static ssize_t dwc3_testmode_write(struct file *file,
    500		const char __user *ubuf, size_t count, loff_t *ppos)
    501{
    502	struct seq_file		*s = file->private_data;
    503	struct dwc3		*dwc = s->private;
    504	unsigned long		flags;
    505	u32			testmode = 0;
    506	char			buf[32];
    507
    508	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
    509		return -EFAULT;
    510
    511	if (!strncmp(buf, "test_j", 6))
    512		testmode = USB_TEST_J;
    513	else if (!strncmp(buf, "test_k", 6))
    514		testmode = USB_TEST_K;
    515	else if (!strncmp(buf, "test_se0_nak", 12))
    516		testmode = USB_TEST_SE0_NAK;
    517	else if (!strncmp(buf, "test_packet", 11))
    518		testmode = USB_TEST_PACKET;
    519	else if (!strncmp(buf, "test_force_enable", 17))
    520		testmode = USB_TEST_FORCE_ENABLE;
    521	else
    522		testmode = 0;
    523
    524	spin_lock_irqsave(&dwc->lock, flags);
    525	dwc3_gadget_set_test_mode(dwc, testmode);
    526	spin_unlock_irqrestore(&dwc->lock, flags);
    527
    528	return count;
    529}
    530
    531static const struct file_operations dwc3_testmode_fops = {
    532	.open			= dwc3_testmode_open,
    533	.write			= dwc3_testmode_write,
    534	.read			= seq_read,
    535	.llseek			= seq_lseek,
    536	.release		= single_release,
    537};
    538
    539static int dwc3_link_state_show(struct seq_file *s, void *unused)
    540{
    541	struct dwc3		*dwc = s->private;
    542	unsigned long		flags;
    543	enum dwc3_link_state	state;
    544	u32			reg;
    545	u8			speed;
    546
    547	spin_lock_irqsave(&dwc->lock, flags);
    548	reg = dwc3_readl(dwc->regs, DWC3_GSTS);
    549	if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
    550		seq_puts(s, "Not available\n");
    551		spin_unlock_irqrestore(&dwc->lock, flags);
    552		return 0;
    553	}
    554
    555	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
    556	state = DWC3_DSTS_USBLNKST(reg);
    557	speed = reg & DWC3_DSTS_CONNECTSPD;
    558
    559	seq_printf(s, "%s\n", (speed >= DWC3_DSTS_SUPERSPEED) ?
    560		   dwc3_gadget_link_string(state) :
    561		   dwc3_gadget_hs_link_string(state));
    562	spin_unlock_irqrestore(&dwc->lock, flags);
    563
    564	return 0;
    565}
    566
    567static int dwc3_link_state_open(struct inode *inode, struct file *file)
    568{
    569	return single_open(file, dwc3_link_state_show, inode->i_private);
    570}
    571
    572static ssize_t dwc3_link_state_write(struct file *file,
    573		const char __user *ubuf, size_t count, loff_t *ppos)
    574{
    575	struct seq_file		*s = file->private_data;
    576	struct dwc3		*dwc = s->private;
    577	unsigned long		flags;
    578	enum dwc3_link_state	state = 0;
    579	char			buf[32];
    580	u32			reg;
    581	u8			speed;
    582
    583	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
    584		return -EFAULT;
    585
    586	if (!strncmp(buf, "SS.Disabled", 11))
    587		state = DWC3_LINK_STATE_SS_DIS;
    588	else if (!strncmp(buf, "Rx.Detect", 9))
    589		state = DWC3_LINK_STATE_RX_DET;
    590	else if (!strncmp(buf, "SS.Inactive", 11))
    591		state = DWC3_LINK_STATE_SS_INACT;
    592	else if (!strncmp(buf, "Recovery", 8))
    593		state = DWC3_LINK_STATE_RECOV;
    594	else if (!strncmp(buf, "Compliance", 10))
    595		state = DWC3_LINK_STATE_CMPLY;
    596	else if (!strncmp(buf, "Loopback", 8))
    597		state = DWC3_LINK_STATE_LPBK;
    598	else
    599		return -EINVAL;
    600
    601	spin_lock_irqsave(&dwc->lock, flags);
    602	reg = dwc3_readl(dwc->regs, DWC3_GSTS);
    603	if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
    604		spin_unlock_irqrestore(&dwc->lock, flags);
    605		return -EINVAL;
    606	}
    607
    608	reg = dwc3_readl(dwc->regs, DWC3_DSTS);
    609	speed = reg & DWC3_DSTS_CONNECTSPD;
    610
    611	if (speed < DWC3_DSTS_SUPERSPEED &&
    612	    state != DWC3_LINK_STATE_RECOV) {
    613		spin_unlock_irqrestore(&dwc->lock, flags);
    614		return -EINVAL;
    615	}
    616
    617	dwc3_gadget_set_link_state(dwc, state);
    618	spin_unlock_irqrestore(&dwc->lock, flags);
    619
    620	return count;
    621}
    622
    623static const struct file_operations dwc3_link_state_fops = {
    624	.open			= dwc3_link_state_open,
    625	.write			= dwc3_link_state_write,
    626	.read			= seq_read,
    627	.llseek			= seq_lseek,
    628	.release		= single_release,
    629};
    630
    631struct dwc3_ep_file_map {
    632	const char name[25];
    633	const struct file_operations *const fops;
    634};
    635
    636static int dwc3_tx_fifo_size_show(struct seq_file *s, void *unused)
    637{
    638	struct dwc3_ep		*dep = s->private;
    639	struct dwc3		*dwc = dep->dwc;
    640	unsigned long		flags;
    641	u32			mdwidth;
    642	u32			val;
    643
    644	spin_lock_irqsave(&dwc->lock, flags);
    645	val = dwc3_core_fifo_space(dep, DWC3_TXFIFO);
    646
    647	/* Convert to bytes */
    648	mdwidth = dwc3_mdwidth(dwc);
    649
    650	val *= mdwidth;
    651	val >>= 3;
    652	seq_printf(s, "%u\n", val);
    653	spin_unlock_irqrestore(&dwc->lock, flags);
    654
    655	return 0;
    656}
    657
    658static int dwc3_rx_fifo_size_show(struct seq_file *s, void *unused)
    659{
    660	struct dwc3_ep		*dep = s->private;
    661	struct dwc3		*dwc = dep->dwc;
    662	unsigned long		flags;
    663	u32			mdwidth;
    664	u32			val;
    665
    666	spin_lock_irqsave(&dwc->lock, flags);
    667	val = dwc3_core_fifo_space(dep, DWC3_RXFIFO);
    668
    669	/* Convert to bytes */
    670	mdwidth = dwc3_mdwidth(dwc);
    671
    672	val *= mdwidth;
    673	val >>= 3;
    674	seq_printf(s, "%u\n", val);
    675	spin_unlock_irqrestore(&dwc->lock, flags);
    676
    677	return 0;
    678}
    679
    680static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused)
    681{
    682	struct dwc3_ep		*dep = s->private;
    683	struct dwc3		*dwc = dep->dwc;
    684	unsigned long		flags;
    685	u32			val;
    686
    687	spin_lock_irqsave(&dwc->lock, flags);
    688	val = dwc3_core_fifo_space(dep, DWC3_TXREQQ);
    689	seq_printf(s, "%u\n", val);
    690	spin_unlock_irqrestore(&dwc->lock, flags);
    691
    692	return 0;
    693}
    694
    695static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused)
    696{
    697	struct dwc3_ep		*dep = s->private;
    698	struct dwc3		*dwc = dep->dwc;
    699	unsigned long		flags;
    700	u32			val;
    701
    702	spin_lock_irqsave(&dwc->lock, flags);
    703	val = dwc3_core_fifo_space(dep, DWC3_RXREQQ);
    704	seq_printf(s, "%u\n", val);
    705	spin_unlock_irqrestore(&dwc->lock, flags);
    706
    707	return 0;
    708}
    709
    710static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused)
    711{
    712	struct dwc3_ep		*dep = s->private;
    713	struct dwc3		*dwc = dep->dwc;
    714	unsigned long		flags;
    715	u32			val;
    716
    717	spin_lock_irqsave(&dwc->lock, flags);
    718	val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ);
    719	seq_printf(s, "%u\n", val);
    720	spin_unlock_irqrestore(&dwc->lock, flags);
    721
    722	return 0;
    723}
    724
    725static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused)
    726{
    727	struct dwc3_ep		*dep = s->private;
    728	struct dwc3		*dwc = dep->dwc;
    729	unsigned long		flags;
    730	u32			val;
    731
    732	spin_lock_irqsave(&dwc->lock, flags);
    733	val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ);
    734	seq_printf(s, "%u\n", val);
    735	spin_unlock_irqrestore(&dwc->lock, flags);
    736
    737	return 0;
    738}
    739
    740static int dwc3_event_queue_show(struct seq_file *s, void *unused)
    741{
    742	struct dwc3_ep		*dep = s->private;
    743	struct dwc3		*dwc = dep->dwc;
    744	unsigned long		flags;
    745	u32			val;
    746
    747	spin_lock_irqsave(&dwc->lock, flags);
    748	val = dwc3_core_fifo_space(dep, DWC3_EVENTQ);
    749	seq_printf(s, "%u\n", val);
    750	spin_unlock_irqrestore(&dwc->lock, flags);
    751
    752	return 0;
    753}
    754
    755static int dwc3_transfer_type_show(struct seq_file *s, void *unused)
    756{
    757	struct dwc3_ep		*dep = s->private;
    758	struct dwc3		*dwc = dep->dwc;
    759	unsigned long		flags;
    760
    761	spin_lock_irqsave(&dwc->lock, flags);
    762	if (!(dep->flags & DWC3_EP_ENABLED) || !dep->endpoint.desc) {
    763		seq_puts(s, "--\n");
    764		goto out;
    765	}
    766
    767	switch (usb_endpoint_type(dep->endpoint.desc)) {
    768	case USB_ENDPOINT_XFER_CONTROL:
    769		seq_puts(s, "control\n");
    770		break;
    771	case USB_ENDPOINT_XFER_ISOC:
    772		seq_puts(s, "isochronous\n");
    773		break;
    774	case USB_ENDPOINT_XFER_BULK:
    775		seq_puts(s, "bulk\n");
    776		break;
    777	case USB_ENDPOINT_XFER_INT:
    778		seq_puts(s, "interrupt\n");
    779		break;
    780	default:
    781		seq_puts(s, "--\n");
    782	}
    783
    784out:
    785	spin_unlock_irqrestore(&dwc->lock, flags);
    786
    787	return 0;
    788}
    789
    790static int dwc3_trb_ring_show(struct seq_file *s, void *unused)
    791{
    792	struct dwc3_ep		*dep = s->private;
    793	struct dwc3		*dwc = dep->dwc;
    794	unsigned long		flags;
    795	int			i;
    796
    797	spin_lock_irqsave(&dwc->lock, flags);
    798	if (dep->number <= 1) {
    799		seq_puts(s, "--\n");
    800		goto out;
    801	}
    802
    803	seq_puts(s, "buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo\n");
    804
    805	for (i = 0; i < DWC3_TRB_NUM; i++) {
    806		struct dwc3_trb *trb = &dep->trb_pool[i];
    807		unsigned int type = DWC3_TRBCTL_TYPE(trb->ctrl);
    808
    809		seq_printf(s, "%08x%08x,%d,%s,%d,%d,%d,%d,%d,%d       %c%c\n",
    810				trb->bph, trb->bpl, trb->size,
    811				dwc3_trb_type_string(type),
    812				!!(trb->ctrl & DWC3_TRB_CTRL_IOC),
    813				!!(trb->ctrl & DWC3_TRB_CTRL_ISP_IMI),
    814				!!(trb->ctrl & DWC3_TRB_CTRL_CSP),
    815				!!(trb->ctrl & DWC3_TRB_CTRL_CHN),
    816				!!(trb->ctrl & DWC3_TRB_CTRL_LST),
    817				!!(trb->ctrl & DWC3_TRB_CTRL_HWO),
    818				dep->trb_enqueue == i ? 'E' : ' ',
    819				dep->trb_dequeue == i ? 'D' : ' ');
    820	}
    821
    822out:
    823	spin_unlock_irqrestore(&dwc->lock, flags);
    824
    825	return 0;
    826}
    827
    828static int dwc3_ep_info_register_show(struct seq_file *s, void *unused)
    829{
    830	struct dwc3_ep		*dep = s->private;
    831	struct dwc3		*dwc = dep->dwc;
    832	unsigned long		flags;
    833	u64			ep_info;
    834	u32			lower_32_bits;
    835	u32			upper_32_bits;
    836	u32			reg;
    837
    838	spin_lock_irqsave(&dwc->lock, flags);
    839	reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number);
    840	dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
    841
    842	lower_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO0);
    843	upper_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO1);
    844
    845	ep_info = ((u64)upper_32_bits << 32) | lower_32_bits;
    846	seq_printf(s, "0x%016llx\n", ep_info);
    847	spin_unlock_irqrestore(&dwc->lock, flags);
    848
    849	return 0;
    850}
    851
    852DEFINE_SHOW_ATTRIBUTE(dwc3_tx_fifo_size);
    853DEFINE_SHOW_ATTRIBUTE(dwc3_rx_fifo_size);
    854DEFINE_SHOW_ATTRIBUTE(dwc3_tx_request_queue);
    855DEFINE_SHOW_ATTRIBUTE(dwc3_rx_request_queue);
    856DEFINE_SHOW_ATTRIBUTE(dwc3_rx_info_queue);
    857DEFINE_SHOW_ATTRIBUTE(dwc3_descriptor_fetch_queue);
    858DEFINE_SHOW_ATTRIBUTE(dwc3_event_queue);
    859DEFINE_SHOW_ATTRIBUTE(dwc3_transfer_type);
    860DEFINE_SHOW_ATTRIBUTE(dwc3_trb_ring);
    861DEFINE_SHOW_ATTRIBUTE(dwc3_ep_info_register);
    862
    863static const struct dwc3_ep_file_map dwc3_ep_file_map[] = {
    864	{ "tx_fifo_size", &dwc3_tx_fifo_size_fops, },
    865	{ "rx_fifo_size", &dwc3_rx_fifo_size_fops, },
    866	{ "tx_request_queue", &dwc3_tx_request_queue_fops, },
    867	{ "rx_request_queue", &dwc3_rx_request_queue_fops, },
    868	{ "rx_info_queue", &dwc3_rx_info_queue_fops, },
    869	{ "descriptor_fetch_queue", &dwc3_descriptor_fetch_queue_fops, },
    870	{ "event_queue", &dwc3_event_queue_fops, },
    871	{ "transfer_type", &dwc3_transfer_type_fops, },
    872	{ "trb_ring", &dwc3_trb_ring_fops, },
    873	{ "GDBGEPINFO", &dwc3_ep_info_register_fops, },
    874};
    875
    876static void dwc3_debugfs_create_endpoint_files(struct dwc3_ep *dep,
    877		struct dentry *parent)
    878{
    879	int			i;
    880
    881	for (i = 0; i < ARRAY_SIZE(dwc3_ep_file_map); i++) {
    882		const struct file_operations *fops = dwc3_ep_file_map[i].fops;
    883		const char *name = dwc3_ep_file_map[i].name;
    884
    885		debugfs_create_file(name, 0444, parent, dep, fops);
    886	}
    887}
    888
    889void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep)
    890{
    891	struct dentry		*dir;
    892	struct dentry		*root;
    893
    894	root = debugfs_lookup(dev_name(dep->dwc->dev), usb_debug_root);
    895	dir = debugfs_create_dir(dep->name, root);
    896	dwc3_debugfs_create_endpoint_files(dep, dir);
    897}
    898
    899void dwc3_debugfs_init(struct dwc3 *dwc)
    900{
    901	struct dentry		*root;
    902
    903	dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL);
    904	if (!dwc->regset)
    905		return;
    906
    907	dwc->dbg_lsp_select = DWC3_LSP_MUX_UNSELECTED;
    908
    909	dwc->regset->regs = dwc3_regs;
    910	dwc->regset->nregs = ARRAY_SIZE(dwc3_regs);
    911	dwc->regset->base = dwc->regs - DWC3_GLOBALS_REGS_START;
    912
    913	root = debugfs_create_dir(dev_name(dwc->dev), usb_debug_root);
    914	debugfs_create_regset32("regdump", 0444, root, dwc->regset);
    915	debugfs_create_file("lsp_dump", 0644, root, dwc, &dwc3_lsp_fops);
    916
    917	if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE))
    918		debugfs_create_file("mode", 0644, root, dwc,
    919				    &dwc3_mode_fops);
    920
    921	if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) ||
    922			IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
    923		debugfs_create_file("testmode", 0644, root, dwc,
    924				&dwc3_testmode_fops);
    925		debugfs_create_file("link_state", 0644, root, dwc,
    926				    &dwc3_link_state_fops);
    927	}
    928}
    929
    930void dwc3_debugfs_exit(struct dwc3 *dwc)
    931{
    932	debugfs_remove(debugfs_lookup(dev_name(dwc->dev), usb_debug_root));
    933	kfree(dwc->regset);
    934}