linux/drivers/usb/dwc3/debugfs.c
<<
>>
Prefs
   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
 631static int dwc3_hiber_enable_show(struct seq_file *s, void *unused)
 632{
 633        struct dwc3             *dwc = s->private;
 634
 635        seq_printf(s, "%s\n", (dwc->has_hibernation ? "Enabled" : "Disabled"));
 636
 637        return 0;
 638}
 639
 640static int dwc3_hiber_enable_open(struct inode *inode, struct file *file)
 641{
 642        return single_open(file, dwc3_hiber_enable_show, inode->i_private);
 643}
 644
 645static ssize_t dwc3_hiber_enable_write(struct file *file,
 646                                       const char __user *ubuf,
 647                                       size_t count, loff_t *ppos)
 648{
 649        struct seq_file         *s = file->private_data;
 650        struct dwc3             *dwc = s->private;
 651        char                    buf[32];
 652
 653        if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
 654                return -EFAULT;
 655
 656        /* Enable hibernation feature */
 657        if (!strncmp(buf, "Enable", 6)) {
 658                dwc3_gadget_exit(dwc);
 659                dwc->has_hibernation = 1;
 660                dwc3_gadget_init(dwc);
 661        } else if (!strncmp(buf, "Disable", 6)) {
 662                dwc3_gadget_exit(dwc);
 663                dwc->has_hibernation = 0;
 664                dwc3_gadget_init(dwc);
 665        } else {
 666                return -EINVAL;
 667        }
 668
 669        return count;
 670}
 671
 672static const struct file_operations dwc3_hiber_enable_fops = {
 673        .open                   = dwc3_hiber_enable_open,
 674        .write                  = dwc3_hiber_enable_write,
 675        .read                   = seq_read,
 676};
 677
 678struct dwc3_ep_file_map {
 679        const char name[25];
 680        const struct file_operations *const fops;
 681};
 682
 683static int dwc3_tx_fifo_size_show(struct seq_file *s, void *unused)
 684{
 685        struct dwc3_ep          *dep = s->private;
 686        struct dwc3             *dwc = dep->dwc;
 687        unsigned long           flags;
 688        int                     mdwidth;
 689        u32                     val;
 690
 691        spin_lock_irqsave(&dwc->lock, flags);
 692        val = dwc3_core_fifo_space(dep, DWC3_TXFIFO);
 693
 694        /* Convert to bytes */
 695        mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
 696        if (DWC3_IP_IS(DWC32))
 697                mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6);
 698
 699        val *= mdwidth;
 700        val >>= 3;
 701        seq_printf(s, "%u\n", val);
 702        spin_unlock_irqrestore(&dwc->lock, flags);
 703
 704        return 0;
 705}
 706
 707static int dwc3_rx_fifo_size_show(struct seq_file *s, void *unused)
 708{
 709        struct dwc3_ep          *dep = s->private;
 710        struct dwc3             *dwc = dep->dwc;
 711        unsigned long           flags;
 712        int                     mdwidth;
 713        u32                     val;
 714
 715        spin_lock_irqsave(&dwc->lock, flags);
 716        val = dwc3_core_fifo_space(dep, DWC3_RXFIFO);
 717
 718        /* Convert to bytes */
 719        mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
 720        if (DWC3_IP_IS(DWC32))
 721                mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6);
 722
 723        val *= mdwidth;
 724        val >>= 3;
 725        seq_printf(s, "%u\n", val);
 726        spin_unlock_irqrestore(&dwc->lock, flags);
 727
 728        return 0;
 729}
 730
 731static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused)
 732{
 733        struct dwc3_ep          *dep = s->private;
 734        struct dwc3             *dwc = dep->dwc;
 735        unsigned long           flags;
 736        u32                     val;
 737
 738        spin_lock_irqsave(&dwc->lock, flags);
 739        val = dwc3_core_fifo_space(dep, DWC3_TXREQQ);
 740        seq_printf(s, "%u\n", val);
 741        spin_unlock_irqrestore(&dwc->lock, flags);
 742
 743        return 0;
 744}
 745
 746static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused)
 747{
 748        struct dwc3_ep          *dep = s->private;
 749        struct dwc3             *dwc = dep->dwc;
 750        unsigned long           flags;
 751        u32                     val;
 752
 753        spin_lock_irqsave(&dwc->lock, flags);
 754        val = dwc3_core_fifo_space(dep, DWC3_RXREQQ);
 755        seq_printf(s, "%u\n", val);
 756        spin_unlock_irqrestore(&dwc->lock, flags);
 757
 758        return 0;
 759}
 760
 761static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused)
 762{
 763        struct dwc3_ep          *dep = s->private;
 764        struct dwc3             *dwc = dep->dwc;
 765        unsigned long           flags;
 766        u32                     val;
 767
 768        spin_lock_irqsave(&dwc->lock, flags);
 769        val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ);
 770        seq_printf(s, "%u\n", val);
 771        spin_unlock_irqrestore(&dwc->lock, flags);
 772
 773        return 0;
 774}
 775
 776static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused)
 777{
 778        struct dwc3_ep          *dep = s->private;
 779        struct dwc3             *dwc = dep->dwc;
 780        unsigned long           flags;
 781        u32                     val;
 782
 783        spin_lock_irqsave(&dwc->lock, flags);
 784        val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ);
 785        seq_printf(s, "%u\n", val);
 786        spin_unlock_irqrestore(&dwc->lock, flags);
 787
 788        return 0;
 789}
 790
 791static int dwc3_event_queue_show(struct seq_file *s, void *unused)
 792{
 793        struct dwc3_ep          *dep = s->private;
 794        struct dwc3             *dwc = dep->dwc;
 795        unsigned long           flags;
 796        u32                     val;
 797
 798        spin_lock_irqsave(&dwc->lock, flags);
 799        val = dwc3_core_fifo_space(dep, DWC3_EVENTQ);
 800        seq_printf(s, "%u\n", val);
 801        spin_unlock_irqrestore(&dwc->lock, flags);
 802
 803        return 0;
 804}
 805
 806static int dwc3_transfer_type_show(struct seq_file *s, void *unused)
 807{
 808        struct dwc3_ep          *dep = s->private;
 809        struct dwc3             *dwc = dep->dwc;
 810        unsigned long           flags;
 811
 812        spin_lock_irqsave(&dwc->lock, flags);
 813        if (!(dep->flags & DWC3_EP_ENABLED) || !dep->endpoint.desc) {
 814                seq_puts(s, "--\n");
 815                goto out;
 816        }
 817
 818        switch (usb_endpoint_type(dep->endpoint.desc)) {
 819        case USB_ENDPOINT_XFER_CONTROL:
 820                seq_puts(s, "control\n");
 821                break;
 822        case USB_ENDPOINT_XFER_ISOC:
 823                seq_puts(s, "isochronous\n");
 824                break;
 825        case USB_ENDPOINT_XFER_BULK:
 826                seq_puts(s, "bulk\n");
 827                break;
 828        case USB_ENDPOINT_XFER_INT:
 829                seq_puts(s, "interrupt\n");
 830                break;
 831        default:
 832                seq_puts(s, "--\n");
 833        }
 834
 835out:
 836        spin_unlock_irqrestore(&dwc->lock, flags);
 837
 838        return 0;
 839}
 840
 841static int dwc3_trb_ring_show(struct seq_file *s, void *unused)
 842{
 843        struct dwc3_ep          *dep = s->private;
 844        struct dwc3             *dwc = dep->dwc;
 845        unsigned long           flags;
 846        int                     i;
 847
 848        spin_lock_irqsave(&dwc->lock, flags);
 849        if (dep->number <= 1) {
 850                seq_puts(s, "--\n");
 851                goto out;
 852        }
 853
 854        seq_puts(s, "buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo\n");
 855
 856        for (i = 0; i < DWC3_TRB_NUM; i++) {
 857                struct dwc3_trb *trb = &dep->trb_pool[i];
 858                unsigned int type = DWC3_TRBCTL_TYPE(trb->ctrl);
 859
 860                seq_printf(s, "%08x%08x,%d,%s,%d,%d,%d,%d,%d,%d       %c%c\n",
 861                                trb->bph, trb->bpl, trb->size,
 862                                dwc3_trb_type_string(type),
 863                                !!(trb->ctrl & DWC3_TRB_CTRL_IOC),
 864                                !!(trb->ctrl & DWC3_TRB_CTRL_ISP_IMI),
 865                                !!(trb->ctrl & DWC3_TRB_CTRL_CSP),
 866                                !!(trb->ctrl & DWC3_TRB_CTRL_CHN),
 867                                !!(trb->ctrl & DWC3_TRB_CTRL_LST),
 868                                !!(trb->ctrl & DWC3_TRB_CTRL_HWO),
 869                                dep->trb_enqueue == i ? 'E' : ' ',
 870                                dep->trb_dequeue == i ? 'D' : ' ');
 871        }
 872
 873out:
 874        spin_unlock_irqrestore(&dwc->lock, flags);
 875
 876        return 0;
 877}
 878
 879static int dwc3_ep_info_register_show(struct seq_file *s, void *unused)
 880{
 881        struct dwc3_ep          *dep = s->private;
 882        struct dwc3             *dwc = dep->dwc;
 883        unsigned long           flags;
 884        u64                     ep_info;
 885        u32                     lower_32_bits;
 886        u32                     upper_32_bits;
 887        u32                     reg;
 888
 889        spin_lock_irqsave(&dwc->lock, flags);
 890        reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number);
 891        dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg);
 892
 893        lower_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO0);
 894        upper_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO1);
 895
 896        ep_info = ((u64)upper_32_bits << 32) | lower_32_bits;
 897        seq_printf(s, "0x%016llx\n", ep_info);
 898        spin_unlock_irqrestore(&dwc->lock, flags);
 899
 900        return 0;
 901}
 902
 903DEFINE_SHOW_ATTRIBUTE(dwc3_tx_fifo_size);
 904DEFINE_SHOW_ATTRIBUTE(dwc3_rx_fifo_size);
 905DEFINE_SHOW_ATTRIBUTE(dwc3_tx_request_queue);
 906DEFINE_SHOW_ATTRIBUTE(dwc3_rx_request_queue);
 907DEFINE_SHOW_ATTRIBUTE(dwc3_rx_info_queue);
 908DEFINE_SHOW_ATTRIBUTE(dwc3_descriptor_fetch_queue);
 909DEFINE_SHOW_ATTRIBUTE(dwc3_event_queue);
 910DEFINE_SHOW_ATTRIBUTE(dwc3_transfer_type);
 911DEFINE_SHOW_ATTRIBUTE(dwc3_trb_ring);
 912DEFINE_SHOW_ATTRIBUTE(dwc3_ep_info_register);
 913
 914static const struct dwc3_ep_file_map dwc3_ep_file_map[] = {
 915        { "tx_fifo_size", &dwc3_tx_fifo_size_fops, },
 916        { "rx_fifo_size", &dwc3_rx_fifo_size_fops, },
 917        { "tx_request_queue", &dwc3_tx_request_queue_fops, },
 918        { "rx_request_queue", &dwc3_rx_request_queue_fops, },
 919        { "rx_info_queue", &dwc3_rx_info_queue_fops, },
 920        { "descriptor_fetch_queue", &dwc3_descriptor_fetch_queue_fops, },
 921        { "event_queue", &dwc3_event_queue_fops, },
 922        { "transfer_type", &dwc3_transfer_type_fops, },
 923        { "trb_ring", &dwc3_trb_ring_fops, },
 924        { "GDBGEPINFO", &dwc3_ep_info_register_fops, },
 925};
 926
 927static void dwc3_debugfs_create_endpoint_files(struct dwc3_ep *dep,
 928                struct dentry *parent)
 929{
 930        int                     i;
 931
 932        for (i = 0; i < ARRAY_SIZE(dwc3_ep_file_map); i++) {
 933                const struct file_operations *fops = dwc3_ep_file_map[i].fops;
 934                const char *name = dwc3_ep_file_map[i].name;
 935
 936                debugfs_create_file(name, 0444, parent, dep, fops);
 937        }
 938}
 939
 940static void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep,
 941                struct dentry *parent)
 942{
 943        struct dentry           *dir;
 944
 945        dir = debugfs_create_dir(dep->name, parent);
 946        dwc3_debugfs_create_endpoint_files(dep, dir);
 947}
 948
 949static void dwc3_debugfs_create_endpoint_dirs(struct dwc3 *dwc,
 950                struct dentry *parent)
 951{
 952        int                     i;
 953
 954        for (i = 0; i < dwc->num_eps; i++) {
 955                struct dwc3_ep  *dep = dwc->eps[i];
 956
 957                if (!dep)
 958                        continue;
 959
 960                dwc3_debugfs_create_endpoint_dir(dep, parent);
 961        }
 962}
 963
 964void dwc3_debugfs_init(struct dwc3 *dwc)
 965{
 966        struct dentry           *root;
 967
 968        dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL);
 969        if (!dwc->regset)
 970                return;
 971
 972        dwc->dbg_lsp_select = DWC3_LSP_MUX_UNSELECTED;
 973
 974        dwc->regset->regs = dwc3_regs;
 975        dwc->regset->nregs = ARRAY_SIZE(dwc3_regs);
 976        dwc->regset->base = dwc->regs - DWC3_GLOBALS_REGS_START;
 977
 978        root = debugfs_create_dir(dev_name(dwc->dev), usb_debug_root);
 979        dwc->root = root;
 980
 981        debugfs_create_regset32("regdump", 0444, root, dwc->regset);
 982        debugfs_create_file("lsp_dump", 0644, root, dwc, &dwc3_lsp_fops);
 983
 984        if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE))
 985                debugfs_create_file("mode", 0644, root, dwc,
 986                                    &dwc3_mode_fops);
 987
 988        if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) ||
 989                        IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
 990                debugfs_create_file("testmode", 0644, root, dwc,
 991                                &dwc3_testmode_fops);
 992                debugfs_create_file("link_state", 0644, root, dwc,
 993                                    &dwc3_link_state_fops);
 994                debugfs_create_file("hiber_enable", S_IRUGO | S_IWUSR, root,
 995                                    dwc, &dwc3_hiber_enable_fops);
 996
 997                dwc3_debugfs_create_endpoint_dirs(dwc, root);
 998        }
 999}
1000
1001void dwc3_debugfs_exit(struct dwc3 *dwc)
1002{
1003        debugfs_remove_recursive(dwc->root);
1004        kfree(dwc->regset);
1005}
1006