Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * debugfs.c - DesignWare USB3 DRD Controller DebugFS file
0004  *
0005  * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
0006  *
0007  * Authors: Felipe Balbi <balbi@ti.com>,
0008  *      Sebastian Andrzej Siewior <bigeasy@linutronix.de>
0009  */
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/slab.h>
0013 #include <linux/ptrace.h>
0014 #include <linux/types.h>
0015 #include <linux/spinlock.h>
0016 #include <linux/debugfs.h>
0017 #include <linux/seq_file.h>
0018 #include <linux/delay.h>
0019 #include <linux/uaccess.h>
0020 
0021 #include <linux/usb/ch9.h>
0022 
0023 #include "core.h"
0024 #include "gadget.h"
0025 #include "io.h"
0026 #include "debug.h"
0027 
0028 #define DWC3_LSP_MUX_UNSELECTED 0xfffff
0029 
0030 #define dump_register(nm)               \
0031 {                           \
0032     .name   = __stringify(nm),          \
0033     .offset = DWC3_ ##nm,               \
0034 }
0035 
0036 #define dump_ep_register_set(n)         \
0037     {                   \
0038         .name = "DEPCMDPAR2("__stringify(n)")", \
0039         .offset = DWC3_DEP_BASE(n) +    \
0040             DWC3_DEPCMDPAR2,    \
0041     },                  \
0042     {                   \
0043         .name = "DEPCMDPAR1("__stringify(n)")", \
0044         .offset = DWC3_DEP_BASE(n) +    \
0045             DWC3_DEPCMDPAR1,    \
0046     },                  \
0047     {                   \
0048         .name = "DEPCMDPAR0("__stringify(n)")", \
0049         .offset = DWC3_DEP_BASE(n) +    \
0050             DWC3_DEPCMDPAR0,    \
0051     },                  \
0052     {                   \
0053         .name = "DEPCMD("__stringify(n)")", \
0054         .offset = DWC3_DEP_BASE(n) +    \
0055             DWC3_DEPCMD,        \
0056     }
0057 
0058 
0059 static const struct debugfs_reg32 dwc3_regs[] = {
0060     dump_register(GSBUSCFG0),
0061     dump_register(GSBUSCFG1),
0062     dump_register(GTXTHRCFG),
0063     dump_register(GRXTHRCFG),
0064     dump_register(GCTL),
0065     dump_register(GEVTEN),
0066     dump_register(GSTS),
0067     dump_register(GUCTL1),
0068     dump_register(GSNPSID),
0069     dump_register(GGPIO),
0070     dump_register(GUID),
0071     dump_register(GUCTL),
0072     dump_register(GBUSERRADDR0),
0073     dump_register(GBUSERRADDR1),
0074     dump_register(GPRTBIMAP0),
0075     dump_register(GPRTBIMAP1),
0076     dump_register(GHWPARAMS0),
0077     dump_register(GHWPARAMS1),
0078     dump_register(GHWPARAMS2),
0079     dump_register(GHWPARAMS3),
0080     dump_register(GHWPARAMS4),
0081     dump_register(GHWPARAMS5),
0082     dump_register(GHWPARAMS6),
0083     dump_register(GHWPARAMS7),
0084     dump_register(GDBGFIFOSPACE),
0085     dump_register(GDBGLTSSM),
0086     dump_register(GDBGBMU),
0087     dump_register(GPRTBIMAP_HS0),
0088     dump_register(GPRTBIMAP_HS1),
0089     dump_register(GPRTBIMAP_FS0),
0090     dump_register(GPRTBIMAP_FS1),
0091 
0092     dump_register(GUSB2PHYCFG(0)),
0093     dump_register(GUSB2PHYCFG(1)),
0094     dump_register(GUSB2PHYCFG(2)),
0095     dump_register(GUSB2PHYCFG(3)),
0096     dump_register(GUSB2PHYCFG(4)),
0097     dump_register(GUSB2PHYCFG(5)),
0098     dump_register(GUSB2PHYCFG(6)),
0099     dump_register(GUSB2PHYCFG(7)),
0100     dump_register(GUSB2PHYCFG(8)),
0101     dump_register(GUSB2PHYCFG(9)),
0102     dump_register(GUSB2PHYCFG(10)),
0103     dump_register(GUSB2PHYCFG(11)),
0104     dump_register(GUSB2PHYCFG(12)),
0105     dump_register(GUSB2PHYCFG(13)),
0106     dump_register(GUSB2PHYCFG(14)),
0107     dump_register(GUSB2PHYCFG(15)),
0108 
0109     dump_register(GUSB2I2CCTL(0)),
0110     dump_register(GUSB2I2CCTL(1)),
0111     dump_register(GUSB2I2CCTL(2)),
0112     dump_register(GUSB2I2CCTL(3)),
0113     dump_register(GUSB2I2CCTL(4)),
0114     dump_register(GUSB2I2CCTL(5)),
0115     dump_register(GUSB2I2CCTL(6)),
0116     dump_register(GUSB2I2CCTL(7)),
0117     dump_register(GUSB2I2CCTL(8)),
0118     dump_register(GUSB2I2CCTL(9)),
0119     dump_register(GUSB2I2CCTL(10)),
0120     dump_register(GUSB2I2CCTL(11)),
0121     dump_register(GUSB2I2CCTL(12)),
0122     dump_register(GUSB2I2CCTL(13)),
0123     dump_register(GUSB2I2CCTL(14)),
0124     dump_register(GUSB2I2CCTL(15)),
0125 
0126     dump_register(GUSB2PHYACC(0)),
0127     dump_register(GUSB2PHYACC(1)),
0128     dump_register(GUSB2PHYACC(2)),
0129     dump_register(GUSB2PHYACC(3)),
0130     dump_register(GUSB2PHYACC(4)),
0131     dump_register(GUSB2PHYACC(5)),
0132     dump_register(GUSB2PHYACC(6)),
0133     dump_register(GUSB2PHYACC(7)),
0134     dump_register(GUSB2PHYACC(8)),
0135     dump_register(GUSB2PHYACC(9)),
0136     dump_register(GUSB2PHYACC(10)),
0137     dump_register(GUSB2PHYACC(11)),
0138     dump_register(GUSB2PHYACC(12)),
0139     dump_register(GUSB2PHYACC(13)),
0140     dump_register(GUSB2PHYACC(14)),
0141     dump_register(GUSB2PHYACC(15)),
0142 
0143     dump_register(GUSB3PIPECTL(0)),
0144     dump_register(GUSB3PIPECTL(1)),
0145     dump_register(GUSB3PIPECTL(2)),
0146     dump_register(GUSB3PIPECTL(3)),
0147     dump_register(GUSB3PIPECTL(4)),
0148     dump_register(GUSB3PIPECTL(5)),
0149     dump_register(GUSB3PIPECTL(6)),
0150     dump_register(GUSB3PIPECTL(7)),
0151     dump_register(GUSB3PIPECTL(8)),
0152     dump_register(GUSB3PIPECTL(9)),
0153     dump_register(GUSB3PIPECTL(10)),
0154     dump_register(GUSB3PIPECTL(11)),
0155     dump_register(GUSB3PIPECTL(12)),
0156     dump_register(GUSB3PIPECTL(13)),
0157     dump_register(GUSB3PIPECTL(14)),
0158     dump_register(GUSB3PIPECTL(15)),
0159 
0160     dump_register(GTXFIFOSIZ(0)),
0161     dump_register(GTXFIFOSIZ(1)),
0162     dump_register(GTXFIFOSIZ(2)),
0163     dump_register(GTXFIFOSIZ(3)),
0164     dump_register(GTXFIFOSIZ(4)),
0165     dump_register(GTXFIFOSIZ(5)),
0166     dump_register(GTXFIFOSIZ(6)),
0167     dump_register(GTXFIFOSIZ(7)),
0168     dump_register(GTXFIFOSIZ(8)),
0169     dump_register(GTXFIFOSIZ(9)),
0170     dump_register(GTXFIFOSIZ(10)),
0171     dump_register(GTXFIFOSIZ(11)),
0172     dump_register(GTXFIFOSIZ(12)),
0173     dump_register(GTXFIFOSIZ(13)),
0174     dump_register(GTXFIFOSIZ(14)),
0175     dump_register(GTXFIFOSIZ(15)),
0176     dump_register(GTXFIFOSIZ(16)),
0177     dump_register(GTXFIFOSIZ(17)),
0178     dump_register(GTXFIFOSIZ(18)),
0179     dump_register(GTXFIFOSIZ(19)),
0180     dump_register(GTXFIFOSIZ(20)),
0181     dump_register(GTXFIFOSIZ(21)),
0182     dump_register(GTXFIFOSIZ(22)),
0183     dump_register(GTXFIFOSIZ(23)),
0184     dump_register(GTXFIFOSIZ(24)),
0185     dump_register(GTXFIFOSIZ(25)),
0186     dump_register(GTXFIFOSIZ(26)),
0187     dump_register(GTXFIFOSIZ(27)),
0188     dump_register(GTXFIFOSIZ(28)),
0189     dump_register(GTXFIFOSIZ(29)),
0190     dump_register(GTXFIFOSIZ(30)),
0191     dump_register(GTXFIFOSIZ(31)),
0192 
0193     dump_register(GRXFIFOSIZ(0)),
0194     dump_register(GRXFIFOSIZ(1)),
0195     dump_register(GRXFIFOSIZ(2)),
0196     dump_register(GRXFIFOSIZ(3)),
0197     dump_register(GRXFIFOSIZ(4)),
0198     dump_register(GRXFIFOSIZ(5)),
0199     dump_register(GRXFIFOSIZ(6)),
0200     dump_register(GRXFIFOSIZ(7)),
0201     dump_register(GRXFIFOSIZ(8)),
0202     dump_register(GRXFIFOSIZ(9)),
0203     dump_register(GRXFIFOSIZ(10)),
0204     dump_register(GRXFIFOSIZ(11)),
0205     dump_register(GRXFIFOSIZ(12)),
0206     dump_register(GRXFIFOSIZ(13)),
0207     dump_register(GRXFIFOSIZ(14)),
0208     dump_register(GRXFIFOSIZ(15)),
0209     dump_register(GRXFIFOSIZ(16)),
0210     dump_register(GRXFIFOSIZ(17)),
0211     dump_register(GRXFIFOSIZ(18)),
0212     dump_register(GRXFIFOSIZ(19)),
0213     dump_register(GRXFIFOSIZ(20)),
0214     dump_register(GRXFIFOSIZ(21)),
0215     dump_register(GRXFIFOSIZ(22)),
0216     dump_register(GRXFIFOSIZ(23)),
0217     dump_register(GRXFIFOSIZ(24)),
0218     dump_register(GRXFIFOSIZ(25)),
0219     dump_register(GRXFIFOSIZ(26)),
0220     dump_register(GRXFIFOSIZ(27)),
0221     dump_register(GRXFIFOSIZ(28)),
0222     dump_register(GRXFIFOSIZ(29)),
0223     dump_register(GRXFIFOSIZ(30)),
0224     dump_register(GRXFIFOSIZ(31)),
0225 
0226     dump_register(GEVNTADRLO(0)),
0227     dump_register(GEVNTADRHI(0)),
0228     dump_register(GEVNTSIZ(0)),
0229     dump_register(GEVNTCOUNT(0)),
0230 
0231     dump_register(GHWPARAMS8),
0232     dump_register(DCFG),
0233     dump_register(DCTL),
0234     dump_register(DEVTEN),
0235     dump_register(DSTS),
0236     dump_register(DGCMDPAR),
0237     dump_register(DGCMD),
0238     dump_register(DALEPENA),
0239 
0240     dump_ep_register_set(0),
0241     dump_ep_register_set(1),
0242     dump_ep_register_set(2),
0243     dump_ep_register_set(3),
0244     dump_ep_register_set(4),
0245     dump_ep_register_set(5),
0246     dump_ep_register_set(6),
0247     dump_ep_register_set(7),
0248     dump_ep_register_set(8),
0249     dump_ep_register_set(9),
0250     dump_ep_register_set(10),
0251     dump_ep_register_set(11),
0252     dump_ep_register_set(12),
0253     dump_ep_register_set(13),
0254     dump_ep_register_set(14),
0255     dump_ep_register_set(15),
0256     dump_ep_register_set(16),
0257     dump_ep_register_set(17),
0258     dump_ep_register_set(18),
0259     dump_ep_register_set(19),
0260     dump_ep_register_set(20),
0261     dump_ep_register_set(21),
0262     dump_ep_register_set(22),
0263     dump_ep_register_set(23),
0264     dump_ep_register_set(24),
0265     dump_ep_register_set(25),
0266     dump_ep_register_set(26),
0267     dump_ep_register_set(27),
0268     dump_ep_register_set(28),
0269     dump_ep_register_set(29),
0270     dump_ep_register_set(30),
0271     dump_ep_register_set(31),
0272 
0273     dump_register(OCFG),
0274     dump_register(OCTL),
0275     dump_register(OEVT),
0276     dump_register(OEVTEN),
0277     dump_register(OSTS),
0278 };
0279 
0280 static void dwc3_host_lsp(struct seq_file *s)
0281 {
0282     struct dwc3     *dwc = s->private;
0283     bool            dbc_enabled;
0284     u32         sel;
0285     u32         reg;
0286     u32         val;
0287 
0288     dbc_enabled = !!(dwc->hwparams.hwparams1 & DWC3_GHWPARAMS1_ENDBC);
0289 
0290     sel = dwc->dbg_lsp_select;
0291     if (sel == DWC3_LSP_MUX_UNSELECTED) {
0292         seq_puts(s, "Write LSP selection to print for host\n");
0293         return;
0294     }
0295 
0296     reg = DWC3_GDBGLSPMUX_HOSTSELECT(sel);
0297 
0298     dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
0299     val = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
0300     seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", sel, val);
0301 
0302     if (dbc_enabled && sel < 256) {
0303         reg |= DWC3_GDBGLSPMUX_ENDBC;
0304         dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
0305         val = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
0306         seq_printf(s, "GDBGLSP_DBC[%d] = 0x%08x\n", sel, val);
0307     }
0308 }
0309 
0310 static void dwc3_gadget_lsp(struct seq_file *s)
0311 {
0312     struct dwc3     *dwc = s->private;
0313     int         i;
0314     u32         reg;
0315 
0316     for (i = 0; i < 16; i++) {
0317         reg = DWC3_GDBGLSPMUX_DEVSELECT(i);
0318         dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
0319         reg = dwc3_readl(dwc->regs, DWC3_GDBGLSP);
0320         seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", i, reg);
0321     }
0322 }
0323 
0324 static int dwc3_lsp_show(struct seq_file *s, void *unused)
0325 {
0326     struct dwc3     *dwc = s->private;
0327     unsigned int        current_mode;
0328     unsigned long       flags;
0329     u32         reg;
0330 
0331     spin_lock_irqsave(&dwc->lock, flags);
0332     reg = dwc3_readl(dwc->regs, DWC3_GSTS);
0333     current_mode = DWC3_GSTS_CURMOD(reg);
0334 
0335     switch (current_mode) {
0336     case DWC3_GSTS_CURMOD_HOST:
0337         dwc3_host_lsp(s);
0338         break;
0339     case DWC3_GSTS_CURMOD_DEVICE:
0340         dwc3_gadget_lsp(s);
0341         break;
0342     default:
0343         seq_puts(s, "Mode is unknown, no LSP register printed\n");
0344         break;
0345     }
0346     spin_unlock_irqrestore(&dwc->lock, flags);
0347 
0348     return 0;
0349 }
0350 
0351 static int dwc3_lsp_open(struct inode *inode, struct file *file)
0352 {
0353     return single_open(file, dwc3_lsp_show, inode->i_private);
0354 }
0355 
0356 static ssize_t dwc3_lsp_write(struct file *file, const char __user *ubuf,
0357                   size_t count, loff_t *ppos)
0358 {
0359     struct seq_file     *s = file->private_data;
0360     struct dwc3     *dwc = s->private;
0361     unsigned long       flags;
0362     char            buf[32] = { 0 };
0363     u32         sel;
0364     int         ret;
0365 
0366     if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
0367         return -EFAULT;
0368 
0369     ret = kstrtouint(buf, 0, &sel);
0370     if (ret)
0371         return ret;
0372 
0373     spin_lock_irqsave(&dwc->lock, flags);
0374     dwc->dbg_lsp_select = sel;
0375     spin_unlock_irqrestore(&dwc->lock, flags);
0376 
0377     return count;
0378 }
0379 
0380 static const struct file_operations dwc3_lsp_fops = {
0381     .open           = dwc3_lsp_open,
0382     .write          = dwc3_lsp_write,
0383     .read           = seq_read,
0384     .llseek         = seq_lseek,
0385     .release        = single_release,
0386 };
0387 
0388 static int dwc3_mode_show(struct seq_file *s, void *unused)
0389 {
0390     struct dwc3     *dwc = s->private;
0391     unsigned long       flags;
0392     u32         reg;
0393 
0394     spin_lock_irqsave(&dwc->lock, flags);
0395     reg = dwc3_readl(dwc->regs, DWC3_GCTL);
0396     spin_unlock_irqrestore(&dwc->lock, flags);
0397 
0398     switch (DWC3_GCTL_PRTCAP(reg)) {
0399     case DWC3_GCTL_PRTCAP_HOST:
0400         seq_puts(s, "host\n");
0401         break;
0402     case DWC3_GCTL_PRTCAP_DEVICE:
0403         seq_puts(s, "device\n");
0404         break;
0405     case DWC3_GCTL_PRTCAP_OTG:
0406         seq_puts(s, "otg\n");
0407         break;
0408     default:
0409         seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg));
0410     }
0411 
0412     return 0;
0413 }
0414 
0415 static int dwc3_mode_open(struct inode *inode, struct file *file)
0416 {
0417     return single_open(file, dwc3_mode_show, inode->i_private);
0418 }
0419 
0420 static ssize_t dwc3_mode_write(struct file *file,
0421         const char __user *ubuf, size_t count, loff_t *ppos)
0422 {
0423     struct seq_file     *s = file->private_data;
0424     struct dwc3     *dwc = s->private;
0425     u32         mode = 0;
0426     char            buf[32];
0427 
0428     if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
0429         return -EFAULT;
0430 
0431     if (dwc->dr_mode != USB_DR_MODE_OTG)
0432         return count;
0433 
0434     if (!strncmp(buf, "host", 4))
0435         mode = DWC3_GCTL_PRTCAP_HOST;
0436 
0437     if (!strncmp(buf, "device", 6))
0438         mode = DWC3_GCTL_PRTCAP_DEVICE;
0439 
0440     if (!strncmp(buf, "otg", 3))
0441         mode = DWC3_GCTL_PRTCAP_OTG;
0442 
0443     dwc3_set_mode(dwc, mode);
0444 
0445     return count;
0446 }
0447 
0448 static const struct file_operations dwc3_mode_fops = {
0449     .open           = dwc3_mode_open,
0450     .write          = dwc3_mode_write,
0451     .read           = seq_read,
0452     .llseek         = seq_lseek,
0453     .release        = single_release,
0454 };
0455 
0456 static int dwc3_testmode_show(struct seq_file *s, void *unused)
0457 {
0458     struct dwc3     *dwc = s->private;
0459     unsigned long       flags;
0460     u32         reg;
0461 
0462     spin_lock_irqsave(&dwc->lock, flags);
0463     reg = dwc3_readl(dwc->regs, DWC3_DCTL);
0464     reg &= DWC3_DCTL_TSTCTRL_MASK;
0465     reg >>= 1;
0466     spin_unlock_irqrestore(&dwc->lock, flags);
0467 
0468     switch (reg) {
0469     case 0:
0470         seq_puts(s, "no test\n");
0471         break;
0472     case USB_TEST_J:
0473         seq_puts(s, "test_j\n");
0474         break;
0475     case USB_TEST_K:
0476         seq_puts(s, "test_k\n");
0477         break;
0478     case USB_TEST_SE0_NAK:
0479         seq_puts(s, "test_se0_nak\n");
0480         break;
0481     case USB_TEST_PACKET:
0482         seq_puts(s, "test_packet\n");
0483         break;
0484     case USB_TEST_FORCE_ENABLE:
0485         seq_puts(s, "test_force_enable\n");
0486         break;
0487     default:
0488         seq_printf(s, "UNKNOWN %d\n", reg);
0489     }
0490 
0491     return 0;
0492 }
0493 
0494 static int dwc3_testmode_open(struct inode *inode, struct file *file)
0495 {
0496     return single_open(file, dwc3_testmode_show, inode->i_private);
0497 }
0498 
0499 static ssize_t dwc3_testmode_write(struct file *file,
0500         const char __user *ubuf, size_t count, loff_t *ppos)
0501 {
0502     struct seq_file     *s = file->private_data;
0503     struct dwc3     *dwc = s->private;
0504     unsigned long       flags;
0505     u32         testmode = 0;
0506     char            buf[32];
0507 
0508     if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
0509         return -EFAULT;
0510 
0511     if (!strncmp(buf, "test_j", 6))
0512         testmode = USB_TEST_J;
0513     else if (!strncmp(buf, "test_k", 6))
0514         testmode = USB_TEST_K;
0515     else if (!strncmp(buf, "test_se0_nak", 12))
0516         testmode = USB_TEST_SE0_NAK;
0517     else if (!strncmp(buf, "test_packet", 11))
0518         testmode = USB_TEST_PACKET;
0519     else if (!strncmp(buf, "test_force_enable", 17))
0520         testmode = USB_TEST_FORCE_ENABLE;
0521     else
0522         testmode = 0;
0523 
0524     spin_lock_irqsave(&dwc->lock, flags);
0525     dwc3_gadget_set_test_mode(dwc, testmode);
0526     spin_unlock_irqrestore(&dwc->lock, flags);
0527 
0528     return count;
0529 }
0530 
0531 static const struct file_operations dwc3_testmode_fops = {
0532     .open           = dwc3_testmode_open,
0533     .write          = dwc3_testmode_write,
0534     .read           = seq_read,
0535     .llseek         = seq_lseek,
0536     .release        = single_release,
0537 };
0538 
0539 static int dwc3_link_state_show(struct seq_file *s, void *unused)
0540 {
0541     struct dwc3     *dwc = s->private;
0542     unsigned long       flags;
0543     enum dwc3_link_state    state;
0544     u32         reg;
0545     u8          speed;
0546 
0547     spin_lock_irqsave(&dwc->lock, flags);
0548     reg = dwc3_readl(dwc->regs, DWC3_GSTS);
0549     if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
0550         seq_puts(s, "Not available\n");
0551         spin_unlock_irqrestore(&dwc->lock, flags);
0552         return 0;
0553     }
0554 
0555     reg = dwc3_readl(dwc->regs, DWC3_DSTS);
0556     state = DWC3_DSTS_USBLNKST(reg);
0557     speed = reg & DWC3_DSTS_CONNECTSPD;
0558 
0559     seq_printf(s, "%s\n", (speed >= DWC3_DSTS_SUPERSPEED) ?
0560            dwc3_gadget_link_string(state) :
0561            dwc3_gadget_hs_link_string(state));
0562     spin_unlock_irqrestore(&dwc->lock, flags);
0563 
0564     return 0;
0565 }
0566 
0567 static int dwc3_link_state_open(struct inode *inode, struct file *file)
0568 {
0569     return single_open(file, dwc3_link_state_show, inode->i_private);
0570 }
0571 
0572 static ssize_t dwc3_link_state_write(struct file *file,
0573         const char __user *ubuf, size_t count, loff_t *ppos)
0574 {
0575     struct seq_file     *s = file->private_data;
0576     struct dwc3     *dwc = s->private;
0577     unsigned long       flags;
0578     enum dwc3_link_state    state = 0;
0579     char            buf[32];
0580     u32         reg;
0581     u8          speed;
0582 
0583     if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
0584         return -EFAULT;
0585 
0586     if (!strncmp(buf, "SS.Disabled", 11))
0587         state = DWC3_LINK_STATE_SS_DIS;
0588     else if (!strncmp(buf, "Rx.Detect", 9))
0589         state = DWC3_LINK_STATE_RX_DET;
0590     else if (!strncmp(buf, "SS.Inactive", 11))
0591         state = DWC3_LINK_STATE_SS_INACT;
0592     else if (!strncmp(buf, "Recovery", 8))
0593         state = DWC3_LINK_STATE_RECOV;
0594     else if (!strncmp(buf, "Compliance", 10))
0595         state = DWC3_LINK_STATE_CMPLY;
0596     else if (!strncmp(buf, "Loopback", 8))
0597         state = DWC3_LINK_STATE_LPBK;
0598     else
0599         return -EINVAL;
0600 
0601     spin_lock_irqsave(&dwc->lock, flags);
0602     reg = dwc3_readl(dwc->regs, DWC3_GSTS);
0603     if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) {
0604         spin_unlock_irqrestore(&dwc->lock, flags);
0605         return -EINVAL;
0606     }
0607 
0608     reg = dwc3_readl(dwc->regs, DWC3_DSTS);
0609     speed = reg & DWC3_DSTS_CONNECTSPD;
0610 
0611     if (speed < DWC3_DSTS_SUPERSPEED &&
0612         state != DWC3_LINK_STATE_RECOV) {
0613         spin_unlock_irqrestore(&dwc->lock, flags);
0614         return -EINVAL;
0615     }
0616 
0617     dwc3_gadget_set_link_state(dwc, state);
0618     spin_unlock_irqrestore(&dwc->lock, flags);
0619 
0620     return count;
0621 }
0622 
0623 static const struct file_operations dwc3_link_state_fops = {
0624     .open           = dwc3_link_state_open,
0625     .write          = dwc3_link_state_write,
0626     .read           = seq_read,
0627     .llseek         = seq_lseek,
0628     .release        = single_release,
0629 };
0630 
0631 struct dwc3_ep_file_map {
0632     const char name[25];
0633     const struct file_operations *const fops;
0634 };
0635 
0636 static int dwc3_tx_fifo_size_show(struct seq_file *s, void *unused)
0637 {
0638     struct dwc3_ep      *dep = s->private;
0639     struct dwc3     *dwc = dep->dwc;
0640     unsigned long       flags;
0641     u32         mdwidth;
0642     u32         val;
0643 
0644     spin_lock_irqsave(&dwc->lock, flags);
0645     val = dwc3_core_fifo_space(dep, DWC3_TXFIFO);
0646 
0647     /* Convert to bytes */
0648     mdwidth = dwc3_mdwidth(dwc);
0649 
0650     val *= mdwidth;
0651     val >>= 3;
0652     seq_printf(s, "%u\n", val);
0653     spin_unlock_irqrestore(&dwc->lock, flags);
0654 
0655     return 0;
0656 }
0657 
0658 static int dwc3_rx_fifo_size_show(struct seq_file *s, void *unused)
0659 {
0660     struct dwc3_ep      *dep = s->private;
0661     struct dwc3     *dwc = dep->dwc;
0662     unsigned long       flags;
0663     u32         mdwidth;
0664     u32         val;
0665 
0666     spin_lock_irqsave(&dwc->lock, flags);
0667     val = dwc3_core_fifo_space(dep, DWC3_RXFIFO);
0668 
0669     /* Convert to bytes */
0670     mdwidth = dwc3_mdwidth(dwc);
0671 
0672     val *= mdwidth;
0673     val >>= 3;
0674     seq_printf(s, "%u\n", val);
0675     spin_unlock_irqrestore(&dwc->lock, flags);
0676 
0677     return 0;
0678 }
0679 
0680 static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused)
0681 {
0682     struct dwc3_ep      *dep = s->private;
0683     struct dwc3     *dwc = dep->dwc;
0684     unsigned long       flags;
0685     u32         val;
0686 
0687     spin_lock_irqsave(&dwc->lock, flags);
0688     val = dwc3_core_fifo_space(dep, DWC3_TXREQQ);
0689     seq_printf(s, "%u\n", val);
0690     spin_unlock_irqrestore(&dwc->lock, flags);
0691 
0692     return 0;
0693 }
0694 
0695 static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused)
0696 {
0697     struct dwc3_ep      *dep = s->private;
0698     struct dwc3     *dwc = dep->dwc;
0699     unsigned long       flags;
0700     u32         val;
0701 
0702     spin_lock_irqsave(&dwc->lock, flags);
0703     val = dwc3_core_fifo_space(dep, DWC3_RXREQQ);
0704     seq_printf(s, "%u\n", val);
0705     spin_unlock_irqrestore(&dwc->lock, flags);
0706 
0707     return 0;
0708 }
0709 
0710 static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused)
0711 {
0712     struct dwc3_ep      *dep = s->private;
0713     struct dwc3     *dwc = dep->dwc;
0714     unsigned long       flags;
0715     u32         val;
0716 
0717     spin_lock_irqsave(&dwc->lock, flags);
0718     val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ);
0719     seq_printf(s, "%u\n", val);
0720     spin_unlock_irqrestore(&dwc->lock, flags);
0721 
0722     return 0;
0723 }
0724 
0725 static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused)
0726 {
0727     struct dwc3_ep      *dep = s->private;
0728     struct dwc3     *dwc = dep->dwc;
0729     unsigned long       flags;
0730     u32         val;
0731 
0732     spin_lock_irqsave(&dwc->lock, flags);
0733     val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ);
0734     seq_printf(s, "%u\n", val);
0735     spin_unlock_irqrestore(&dwc->lock, flags);
0736 
0737     return 0;
0738 }
0739 
0740 static int dwc3_event_queue_show(struct seq_file *s, void *unused)
0741 {
0742     struct dwc3_ep      *dep = s->private;
0743     struct dwc3     *dwc = dep->dwc;
0744     unsigned long       flags;
0745     u32         val;
0746 
0747     spin_lock_irqsave(&dwc->lock, flags);
0748     val = dwc3_core_fifo_space(dep, DWC3_EVENTQ);
0749     seq_printf(s, "%u\n", val);
0750     spin_unlock_irqrestore(&dwc->lock, flags);
0751 
0752     return 0;
0753 }
0754 
0755 static int dwc3_transfer_type_show(struct seq_file *s, void *unused)
0756 {
0757     struct dwc3_ep      *dep = s->private;
0758     struct dwc3     *dwc = dep->dwc;
0759     unsigned long       flags;
0760 
0761     spin_lock_irqsave(&dwc->lock, flags);
0762     if (!(dep->flags & DWC3_EP_ENABLED) || !dep->endpoint.desc) {
0763         seq_puts(s, "--\n");
0764         goto out;
0765     }
0766 
0767     switch (usb_endpoint_type(dep->endpoint.desc)) {
0768     case USB_ENDPOINT_XFER_CONTROL:
0769         seq_puts(s, "control\n");
0770         break;
0771     case USB_ENDPOINT_XFER_ISOC:
0772         seq_puts(s, "isochronous\n");
0773         break;
0774     case USB_ENDPOINT_XFER_BULK:
0775         seq_puts(s, "bulk\n");
0776         break;
0777     case USB_ENDPOINT_XFER_INT:
0778         seq_puts(s, "interrupt\n");
0779         break;
0780     default:
0781         seq_puts(s, "--\n");
0782     }
0783 
0784 out:
0785     spin_unlock_irqrestore(&dwc->lock, flags);
0786 
0787     return 0;
0788 }
0789 
0790 static int dwc3_trb_ring_show(struct seq_file *s, void *unused)
0791 {
0792     struct dwc3_ep      *dep = s->private;
0793     struct dwc3     *dwc = dep->dwc;
0794     unsigned long       flags;
0795     int         i;
0796 
0797     spin_lock_irqsave(&dwc->lock, flags);
0798     if (dep->number <= 1) {
0799         seq_puts(s, "--\n");
0800         goto out;
0801     }
0802 
0803     seq_puts(s, "buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo\n");
0804 
0805     for (i = 0; i < DWC3_TRB_NUM; i++) {
0806         struct dwc3_trb *trb = &dep->trb_pool[i];
0807         unsigned int type = DWC3_TRBCTL_TYPE(trb->ctrl);
0808 
0809         seq_printf(s, "%08x%08x,%d,%s,%d,%d,%d,%d,%d,%d       %c%c\n",
0810                 trb->bph, trb->bpl, trb->size,
0811                 dwc3_trb_type_string(type),
0812                 !!(trb->ctrl & DWC3_TRB_CTRL_IOC),
0813                 !!(trb->ctrl & DWC3_TRB_CTRL_ISP_IMI),
0814                 !!(trb->ctrl & DWC3_TRB_CTRL_CSP),
0815                 !!(trb->ctrl & DWC3_TRB_CTRL_CHN),
0816                 !!(trb->ctrl & DWC3_TRB_CTRL_LST),
0817                 !!(trb->ctrl & DWC3_TRB_CTRL_HWO),
0818                 dep->trb_enqueue == i ? 'E' : ' ',
0819                 dep->trb_dequeue == i ? 'D' : ' ');
0820     }
0821 
0822 out:
0823     spin_unlock_irqrestore(&dwc->lock, flags);
0824 
0825     return 0;
0826 }
0827 
0828 static int dwc3_ep_info_register_show(struct seq_file *s, void *unused)
0829 {
0830     struct dwc3_ep      *dep = s->private;
0831     struct dwc3     *dwc = dep->dwc;
0832     unsigned long       flags;
0833     u64         ep_info;
0834     u32         lower_32_bits;
0835     u32         upper_32_bits;
0836     u32         reg;
0837 
0838     spin_lock_irqsave(&dwc->lock, flags);
0839     reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number);
0840     dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
0841 
0842     lower_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO0);
0843     upper_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO1);
0844 
0845     ep_info = ((u64)upper_32_bits << 32) | lower_32_bits;
0846     seq_printf(s, "0x%016llx\n", ep_info);
0847     spin_unlock_irqrestore(&dwc->lock, flags);
0848 
0849     return 0;
0850 }
0851 
0852 DEFINE_SHOW_ATTRIBUTE(dwc3_tx_fifo_size);
0853 DEFINE_SHOW_ATTRIBUTE(dwc3_rx_fifo_size);
0854 DEFINE_SHOW_ATTRIBUTE(dwc3_tx_request_queue);
0855 DEFINE_SHOW_ATTRIBUTE(dwc3_rx_request_queue);
0856 DEFINE_SHOW_ATTRIBUTE(dwc3_rx_info_queue);
0857 DEFINE_SHOW_ATTRIBUTE(dwc3_descriptor_fetch_queue);
0858 DEFINE_SHOW_ATTRIBUTE(dwc3_event_queue);
0859 DEFINE_SHOW_ATTRIBUTE(dwc3_transfer_type);
0860 DEFINE_SHOW_ATTRIBUTE(dwc3_trb_ring);
0861 DEFINE_SHOW_ATTRIBUTE(dwc3_ep_info_register);
0862 
0863 static const struct dwc3_ep_file_map dwc3_ep_file_map[] = {
0864     { "tx_fifo_size", &dwc3_tx_fifo_size_fops, },
0865     { "rx_fifo_size", &dwc3_rx_fifo_size_fops, },
0866     { "tx_request_queue", &dwc3_tx_request_queue_fops, },
0867     { "rx_request_queue", &dwc3_rx_request_queue_fops, },
0868     { "rx_info_queue", &dwc3_rx_info_queue_fops, },
0869     { "descriptor_fetch_queue", &dwc3_descriptor_fetch_queue_fops, },
0870     { "event_queue", &dwc3_event_queue_fops, },
0871     { "transfer_type", &dwc3_transfer_type_fops, },
0872     { "trb_ring", &dwc3_trb_ring_fops, },
0873     { "GDBGEPINFO", &dwc3_ep_info_register_fops, },
0874 };
0875 
0876 static void dwc3_debugfs_create_endpoint_files(struct dwc3_ep *dep,
0877         struct dentry *parent)
0878 {
0879     int         i;
0880 
0881     for (i = 0; i < ARRAY_SIZE(dwc3_ep_file_map); i++) {
0882         const struct file_operations *fops = dwc3_ep_file_map[i].fops;
0883         const char *name = dwc3_ep_file_map[i].name;
0884 
0885         debugfs_create_file(name, 0444, parent, dep, fops);
0886     }
0887 }
0888 
0889 void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep)
0890 {
0891     struct dentry       *dir;
0892     struct dentry       *root;
0893 
0894     root = debugfs_lookup(dev_name(dep->dwc->dev), usb_debug_root);
0895     dir = debugfs_create_dir(dep->name, root);
0896     dwc3_debugfs_create_endpoint_files(dep, dir);
0897 }
0898 
0899 void dwc3_debugfs_init(struct dwc3 *dwc)
0900 {
0901     struct dentry       *root;
0902 
0903     dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL);
0904     if (!dwc->regset)
0905         return;
0906 
0907     dwc->dbg_lsp_select = DWC3_LSP_MUX_UNSELECTED;
0908 
0909     dwc->regset->regs = dwc3_regs;
0910     dwc->regset->nregs = ARRAY_SIZE(dwc3_regs);
0911     dwc->regset->base = dwc->regs - DWC3_GLOBALS_REGS_START;
0912 
0913     root = debugfs_create_dir(dev_name(dwc->dev), usb_debug_root);
0914     debugfs_create_regset32("regdump", 0444, root, dwc->regset);
0915     debugfs_create_file("lsp_dump", 0644, root, dwc, &dwc3_lsp_fops);
0916 
0917     if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE))
0918         debugfs_create_file("mode", 0644, root, dwc,
0919                     &dwc3_mode_fops);
0920 
0921     if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) ||
0922             IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
0923         debugfs_create_file("testmode", 0644, root, dwc,
0924                 &dwc3_testmode_fops);
0925         debugfs_create_file("link_state", 0644, root, dwc,
0926                     &dwc3_link_state_fops);
0927     }
0928 }
0929 
0930 void dwc3_debugfs_exit(struct dwc3 *dwc)
0931 {
0932     debugfs_remove(debugfs_lookup(dev_name(dwc->dev), usb_debug_root));
0933     kfree(dwc->regset);
0934 }