linux/drivers/usb/dwc3/debugfs.c
<<
>>
Prefs
   1/**
   2 * debugfs.c - DesignWare USB3 DRD Controller DebugFS file
   3 *
   4 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
   5 *
   6 * Authors: Felipe Balbi <balbi@ti.com>,
   7 *          Sebastian Andrzej Siewior <bigeasy@linutronix.de>
   8 *
   9 * This program is free software: you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2  of
  11 * the License as published by the Free Software Foundation.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 */
  18
  19#include <linux/kernel.h>
  20#include <linux/slab.h>
  21#include <linux/ptrace.h>
  22#include <linux/types.h>
  23#include <linux/spinlock.h>
  24#include <linux/debugfs.h>
  25#include <linux/seq_file.h>
  26#include <linux/delay.h>
  27#include <linux/uaccess.h>
  28
  29#include <linux/usb/ch9.h>
  30
  31#include "core.h"
  32#include "gadget.h"
  33#include "io.h"
  34#include "debug.h"
  35
  36#define dump_register(nm)                               \
  37{                                                       \
  38        .name   = __stringify(nm),                      \
  39        .offset = DWC3_ ##nm,                           \
  40}
  41
  42#define dump_ep_register_set(n)                 \
  43        {                                       \
  44                .name = "DEPCMDPAR2("__stringify(n)")", \
  45                .offset = DWC3_DEP_BASE(n) +    \
  46                        DWC3_DEPCMDPAR2,        \
  47        },                                      \
  48        {                                       \
  49                .name = "DEPCMDPAR1("__stringify(n)")", \
  50                .offset = DWC3_DEP_BASE(n) +    \
  51                        DWC3_DEPCMDPAR1,        \
  52        },                                      \
  53        {                                       \
  54                .name = "DEPCMDPAR0("__stringify(n)")", \
  55                .offset = DWC3_DEP_BASE(n) +    \
  56                        DWC3_DEPCMDPAR0,        \
  57        },                                      \
  58        {                                       \
  59                .name = "DEPCMD("__stringify(n)")",     \
  60                .offset = DWC3_DEP_BASE(n) +    \
  61                        DWC3_DEPCMD,            \
  62        }
  63
  64
  65static const struct debugfs_reg32 dwc3_regs[] = {
  66        dump_register(GSBUSCFG0),
  67        dump_register(GSBUSCFG1),
  68        dump_register(GTXTHRCFG),
  69        dump_register(GRXTHRCFG),
  70        dump_register(GCTL),
  71        dump_register(GEVTEN),
  72        dump_register(GSTS),
  73        dump_register(GUCTL1),
  74        dump_register(GSNPSID),
  75        dump_register(GGPIO),
  76        dump_register(GUID),
  77        dump_register(GUCTL),
  78        dump_register(GBUSERRADDR0),
  79        dump_register(GBUSERRADDR1),
  80        dump_register(GPRTBIMAP0),
  81        dump_register(GPRTBIMAP1),
  82        dump_register(GHWPARAMS0),
  83        dump_register(GHWPARAMS1),
  84        dump_register(GHWPARAMS2),
  85        dump_register(GHWPARAMS3),
  86        dump_register(GHWPARAMS4),
  87        dump_register(GHWPARAMS5),
  88        dump_register(GHWPARAMS6),
  89        dump_register(GHWPARAMS7),
  90        dump_register(GDBGFIFOSPACE),
  91        dump_register(GDBGLTSSM),
  92        dump_register(GPRTBIMAP_HS0),
  93        dump_register(GPRTBIMAP_HS1),
  94        dump_register(GPRTBIMAP_FS0),
  95        dump_register(GPRTBIMAP_FS1),
  96
  97        dump_register(GUSB2PHYCFG(0)),
  98        dump_register(GUSB2PHYCFG(1)),
  99        dump_register(GUSB2PHYCFG(2)),
 100        dump_register(GUSB2PHYCFG(3)),
 101        dump_register(GUSB2PHYCFG(4)),
 102        dump_register(GUSB2PHYCFG(5)),
 103        dump_register(GUSB2PHYCFG(6)),
 104        dump_register(GUSB2PHYCFG(7)),
 105        dump_register(GUSB2PHYCFG(8)),
 106        dump_register(GUSB2PHYCFG(9)),
 107        dump_register(GUSB2PHYCFG(10)),
 108        dump_register(GUSB2PHYCFG(11)),
 109        dump_register(GUSB2PHYCFG(12)),
 110        dump_register(GUSB2PHYCFG(13)),
 111        dump_register(GUSB2PHYCFG(14)),
 112        dump_register(GUSB2PHYCFG(15)),
 113
 114        dump_register(GUSB2I2CCTL(0)),
 115        dump_register(GUSB2I2CCTL(1)),
 116        dump_register(GUSB2I2CCTL(2)),
 117        dump_register(GUSB2I2CCTL(3)),
 118        dump_register(GUSB2I2CCTL(4)),
 119        dump_register(GUSB2I2CCTL(5)),
 120        dump_register(GUSB2I2CCTL(6)),
 121        dump_register(GUSB2I2CCTL(7)),
 122        dump_register(GUSB2I2CCTL(8)),
 123        dump_register(GUSB2I2CCTL(9)),
 124        dump_register(GUSB2I2CCTL(10)),
 125        dump_register(GUSB2I2CCTL(11)),
 126        dump_register(GUSB2I2CCTL(12)),
 127        dump_register(GUSB2I2CCTL(13)),
 128        dump_register(GUSB2I2CCTL(14)),
 129        dump_register(GUSB2I2CCTL(15)),
 130
 131        dump_register(GUSB2PHYACC(0)),
 132        dump_register(GUSB2PHYACC(1)),
 133        dump_register(GUSB2PHYACC(2)),
 134        dump_register(GUSB2PHYACC(3)),
 135        dump_register(GUSB2PHYACC(4)),
 136        dump_register(GUSB2PHYACC(5)),
 137        dump_register(GUSB2PHYACC(6)),
 138        dump_register(GUSB2PHYACC(7)),
 139        dump_register(GUSB2PHYACC(8)),
 140        dump_register(GUSB2PHYACC(9)),
 141        dump_register(GUSB2PHYACC(10)),
 142        dump_register(GUSB2PHYACC(11)),
 143        dump_register(GUSB2PHYACC(12)),
 144        dump_register(GUSB2PHYACC(13)),
 145        dump_register(GUSB2PHYACC(14)),
 146        dump_register(GUSB2PHYACC(15)),
 147
 148        dump_register(GUSB3PIPECTL(0)),
 149        dump_register(GUSB3PIPECTL(1)),
 150        dump_register(GUSB3PIPECTL(2)),
 151        dump_register(GUSB3PIPECTL(3)),
 152        dump_register(GUSB3PIPECTL(4)),
 153        dump_register(GUSB3PIPECTL(5)),
 154        dump_register(GUSB3PIPECTL(6)),
 155        dump_register(GUSB3PIPECTL(7)),
 156        dump_register(GUSB3PIPECTL(8)),
 157        dump_register(GUSB3PIPECTL(9)),
 158        dump_register(GUSB3PIPECTL(10)),
 159        dump_register(GUSB3PIPECTL(11)),
 160        dump_register(GUSB3PIPECTL(12)),
 161        dump_register(GUSB3PIPECTL(13)),
 162        dump_register(GUSB3PIPECTL(14)),
 163        dump_register(GUSB3PIPECTL(15)),
 164
 165        dump_register(GTXFIFOSIZ(0)),
 166        dump_register(GTXFIFOSIZ(1)),
 167        dump_register(GTXFIFOSIZ(2)),
 168        dump_register(GTXFIFOSIZ(3)),
 169        dump_register(GTXFIFOSIZ(4)),
 170        dump_register(GTXFIFOSIZ(5)),
 171        dump_register(GTXFIFOSIZ(6)),
 172        dump_register(GTXFIFOSIZ(7)),
 173        dump_register(GTXFIFOSIZ(8)),
 174        dump_register(GTXFIFOSIZ(9)),
 175        dump_register(GTXFIFOSIZ(10)),
 176        dump_register(GTXFIFOSIZ(11)),
 177        dump_register(GTXFIFOSIZ(12)),
 178        dump_register(GTXFIFOSIZ(13)),
 179        dump_register(GTXFIFOSIZ(14)),
 180        dump_register(GTXFIFOSIZ(15)),
 181        dump_register(GTXFIFOSIZ(16)),
 182        dump_register(GTXFIFOSIZ(17)),
 183        dump_register(GTXFIFOSIZ(18)),
 184        dump_register(GTXFIFOSIZ(19)),
 185        dump_register(GTXFIFOSIZ(20)),
 186        dump_register(GTXFIFOSIZ(21)),
 187        dump_register(GTXFIFOSIZ(22)),
 188        dump_register(GTXFIFOSIZ(23)),
 189        dump_register(GTXFIFOSIZ(24)),
 190        dump_register(GTXFIFOSIZ(25)),
 191        dump_register(GTXFIFOSIZ(26)),
 192        dump_register(GTXFIFOSIZ(27)),
 193        dump_register(GTXFIFOSIZ(28)),
 194        dump_register(GTXFIFOSIZ(29)),
 195        dump_register(GTXFIFOSIZ(30)),
 196        dump_register(GTXFIFOSIZ(31)),
 197
 198        dump_register(GRXFIFOSIZ(0)),
 199        dump_register(GRXFIFOSIZ(1)),
 200        dump_register(GRXFIFOSIZ(2)),
 201        dump_register(GRXFIFOSIZ(3)),
 202        dump_register(GRXFIFOSIZ(4)),
 203        dump_register(GRXFIFOSIZ(5)),
 204        dump_register(GRXFIFOSIZ(6)),
 205        dump_register(GRXFIFOSIZ(7)),
 206        dump_register(GRXFIFOSIZ(8)),
 207        dump_register(GRXFIFOSIZ(9)),
 208        dump_register(GRXFIFOSIZ(10)),
 209        dump_register(GRXFIFOSIZ(11)),
 210        dump_register(GRXFIFOSIZ(12)),
 211        dump_register(GRXFIFOSIZ(13)),
 212        dump_register(GRXFIFOSIZ(14)),
 213        dump_register(GRXFIFOSIZ(15)),
 214        dump_register(GRXFIFOSIZ(16)),
 215        dump_register(GRXFIFOSIZ(17)),
 216        dump_register(GRXFIFOSIZ(18)),
 217        dump_register(GRXFIFOSIZ(19)),
 218        dump_register(GRXFIFOSIZ(20)),
 219        dump_register(GRXFIFOSIZ(21)),
 220        dump_register(GRXFIFOSIZ(22)),
 221        dump_register(GRXFIFOSIZ(23)),
 222        dump_register(GRXFIFOSIZ(24)),
 223        dump_register(GRXFIFOSIZ(25)),
 224        dump_register(GRXFIFOSIZ(26)),
 225        dump_register(GRXFIFOSIZ(27)),
 226        dump_register(GRXFIFOSIZ(28)),
 227        dump_register(GRXFIFOSIZ(29)),
 228        dump_register(GRXFIFOSIZ(30)),
 229        dump_register(GRXFIFOSIZ(31)),
 230
 231        dump_register(GEVNTADRLO(0)),
 232        dump_register(GEVNTADRHI(0)),
 233        dump_register(GEVNTSIZ(0)),
 234        dump_register(GEVNTCOUNT(0)),
 235
 236        dump_register(GHWPARAMS8),
 237        dump_register(DCFG),
 238        dump_register(DCTL),
 239        dump_register(DEVTEN),
 240        dump_register(DSTS),
 241        dump_register(DGCMDPAR),
 242        dump_register(DGCMD),
 243        dump_register(DALEPENA),
 244
 245        dump_ep_register_set(0),
 246        dump_ep_register_set(1),
 247        dump_ep_register_set(2),
 248        dump_ep_register_set(3),
 249        dump_ep_register_set(4),
 250        dump_ep_register_set(5),
 251        dump_ep_register_set(6),
 252        dump_ep_register_set(7),
 253        dump_ep_register_set(8),
 254        dump_ep_register_set(9),
 255        dump_ep_register_set(10),
 256        dump_ep_register_set(11),
 257        dump_ep_register_set(12),
 258        dump_ep_register_set(13),
 259        dump_ep_register_set(14),
 260        dump_ep_register_set(15),
 261        dump_ep_register_set(16),
 262        dump_ep_register_set(17),
 263        dump_ep_register_set(18),
 264        dump_ep_register_set(19),
 265        dump_ep_register_set(20),
 266        dump_ep_register_set(21),
 267        dump_ep_register_set(22),
 268        dump_ep_register_set(23),
 269        dump_ep_register_set(24),
 270        dump_ep_register_set(25),
 271        dump_ep_register_set(26),
 272        dump_ep_register_set(27),
 273        dump_ep_register_set(28),
 274        dump_ep_register_set(29),
 275        dump_ep_register_set(30),
 276        dump_ep_register_set(31),
 277
 278        dump_register(OCFG),
 279        dump_register(OCTL),
 280        dump_register(OEVT),
 281        dump_register(OEVTEN),
 282        dump_register(OSTS),
 283};
 284
 285static int dwc3_mode_show(struct seq_file *s, void *unused)
 286{
 287        struct dwc3             *dwc = s->private;
 288        unsigned long           flags;
 289        u32                     reg;
 290
 291        spin_lock_irqsave(&dwc->lock, flags);
 292        reg = dwc3_readl(dwc->regs, DWC3_GCTL);
 293        spin_unlock_irqrestore(&dwc->lock, flags);
 294
 295        switch (DWC3_GCTL_PRTCAP(reg)) {
 296        case DWC3_GCTL_PRTCAP_HOST:
 297                seq_printf(s, "host\n");
 298                break;
 299        case DWC3_GCTL_PRTCAP_DEVICE:
 300                seq_printf(s, "device\n");
 301                break;
 302        case DWC3_GCTL_PRTCAP_OTG:
 303                seq_printf(s, "otg\n");
 304                break;
 305        default:
 306                seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg));
 307        }
 308
 309        return 0;
 310}
 311
 312static int dwc3_mode_open(struct inode *inode, struct file *file)
 313{
 314        return single_open(file, dwc3_mode_show, inode->i_private);
 315}
 316
 317static ssize_t dwc3_mode_write(struct file *file,
 318                const char __user *ubuf, size_t count, loff_t *ppos)
 319{
 320        struct seq_file         *s = file->private_data;
 321        struct dwc3             *dwc = s->private;
 322        u32                     mode = 0;
 323        char                    buf[32];
 324
 325        if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
 326                return -EFAULT;
 327
 328        if (!strncmp(buf, "host", 4))
 329                mode = DWC3_GCTL_PRTCAP_HOST;
 330
 331        if (!strncmp(buf, "device", 6))
 332                mode = DWC3_GCTL_PRTCAP_DEVICE;
 333
 334        if (!strncmp(buf, "otg", 3))
 335                mode = DWC3_GCTL_PRTCAP_OTG;
 336
 337        dwc3_set_mode(dwc, mode);
 338
 339        return count;
 340}
 341
 342static const struct file_operations dwc3_mode_fops = {
 343        .open                   = dwc3_mode_open,
 344        .write                  = dwc3_mode_write,
 345        .read                   = seq_read,
 346        .llseek                 = seq_lseek,
 347        .release                = single_release,
 348};
 349
 350static int dwc3_testmode_show(struct seq_file *s, void *unused)
 351{
 352        struct dwc3             *dwc = s->private;
 353        unsigned long           flags;
 354        u32                     reg;
 355
 356        spin_lock_irqsave(&dwc->lock, flags);
 357        reg = dwc3_readl(dwc->regs, DWC3_DCTL);
 358        reg &= DWC3_DCTL_TSTCTRL_MASK;
 359        reg >>= 1;
 360        spin_unlock_irqrestore(&dwc->lock, flags);
 361
 362        switch (reg) {
 363        case 0:
 364                seq_printf(s, "no test\n");
 365                break;
 366        case TEST_J:
 367                seq_printf(s, "test_j\n");
 368                break;
 369        case TEST_K:
 370                seq_printf(s, "test_k\n");
 371                break;
 372        case TEST_SE0_NAK:
 373                seq_printf(s, "test_se0_nak\n");
 374                break;
 375        case TEST_PACKET:
 376                seq_printf(s, "test_packet\n");
 377                break;
 378        case TEST_FORCE_EN:
 379                seq_printf(s, "test_force_enable\n");
 380                break;
 381        default:
 382                seq_printf(s, "UNKNOWN %d\n", reg);
 383        }
 384
 385        return 0;
 386}
 387
 388static int dwc3_testmode_open(struct inode *inode, struct file *file)
 389{
 390        return single_open(file, dwc3_testmode_show, inode->i_private);
 391}
 392
 393static ssize_t dwc3_testmode_write(struct file *file,
 394                const char __user *ubuf, size_t count, loff_t *ppos)
 395{
 396        struct seq_file         *s = file->private_data;
 397        struct dwc3             *dwc = s->private;
 398        unsigned long           flags;
 399        u32                     testmode = 0;
 400        char                    buf[32];
 401
 402        if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
 403                return -EFAULT;
 404
 405        if (!strncmp(buf, "test_j", 6))
 406                testmode = TEST_J;
 407        else if (!strncmp(buf, "test_k", 6))
 408                testmode = TEST_K;
 409        else if (!strncmp(buf, "test_se0_nak", 12))
 410                testmode = TEST_SE0_NAK;
 411        else if (!strncmp(buf, "test_packet", 11))
 412                testmode = TEST_PACKET;
 413        else if (!strncmp(buf, "test_force_enable", 17))
 414                testmode = TEST_FORCE_EN;
 415        else
 416                testmode = 0;
 417
 418        spin_lock_irqsave(&dwc->lock, flags);
 419        dwc3_gadget_set_test_mode(dwc, testmode);
 420        spin_unlock_irqrestore(&dwc->lock, flags);
 421
 422        return count;
 423}
 424
 425static const struct file_operations dwc3_testmode_fops = {
 426        .open                   = dwc3_testmode_open,
 427        .write                  = dwc3_testmode_write,
 428        .read                   = seq_read,
 429        .llseek                 = seq_lseek,
 430        .release                = single_release,
 431};
 432
 433static int dwc3_link_state_show(struct seq_file *s, void *unused)
 434{
 435        struct dwc3             *dwc = s->private;
 436        unsigned long           flags;
 437        enum dwc3_link_state    state;
 438        u32                     reg;
 439
 440        spin_lock_irqsave(&dwc->lock, flags);
 441        reg = dwc3_readl(dwc->regs, DWC3_DSTS);
 442        state = DWC3_DSTS_USBLNKST(reg);
 443        spin_unlock_irqrestore(&dwc->lock, flags);
 444
 445        seq_printf(s, "%s\n", dwc3_gadget_link_string(state));
 446
 447        return 0;
 448}
 449
 450static int dwc3_link_state_open(struct inode *inode, struct file *file)
 451{
 452        return single_open(file, dwc3_link_state_show, inode->i_private);
 453}
 454
 455static ssize_t dwc3_link_state_write(struct file *file,
 456                const char __user *ubuf, size_t count, loff_t *ppos)
 457{
 458        struct seq_file         *s = file->private_data;
 459        struct dwc3             *dwc = s->private;
 460        unsigned long           flags;
 461        enum dwc3_link_state    state = 0;
 462        char                    buf[32];
 463
 464        if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
 465                return -EFAULT;
 466
 467        if (!strncmp(buf, "SS.Disabled", 11))
 468                state = DWC3_LINK_STATE_SS_DIS;
 469        else if (!strncmp(buf, "Rx.Detect", 9))
 470                state = DWC3_LINK_STATE_RX_DET;
 471        else if (!strncmp(buf, "SS.Inactive", 11))
 472                state = DWC3_LINK_STATE_SS_INACT;
 473        else if (!strncmp(buf, "Recovery", 8))
 474                state = DWC3_LINK_STATE_RECOV;
 475        else if (!strncmp(buf, "Compliance", 10))
 476                state = DWC3_LINK_STATE_CMPLY;
 477        else if (!strncmp(buf, "Loopback", 8))
 478                state = DWC3_LINK_STATE_LPBK;
 479        else
 480                return -EINVAL;
 481
 482        spin_lock_irqsave(&dwc->lock, flags);
 483        dwc3_gadget_set_link_state(dwc, state);
 484        spin_unlock_irqrestore(&dwc->lock, flags);
 485
 486        return count;
 487}
 488
 489static const struct file_operations dwc3_link_state_fops = {
 490        .open                   = dwc3_link_state_open,
 491        .write                  = dwc3_link_state_write,
 492        .read                   = seq_read,
 493        .llseek                 = seq_lseek,
 494        .release                = single_release,
 495};
 496
 497struct dwc3_ep_file_map {
 498        char name[25];
 499        int (*show)(struct seq_file *s, void *unused);
 500};
 501
 502static int dwc3_tx_fifo_queue_show(struct seq_file *s, void *unused)
 503{
 504        struct dwc3_ep          *dep = s->private;
 505        struct dwc3             *dwc = dep->dwc;
 506        unsigned long           flags;
 507        u32                     val;
 508
 509        spin_lock_irqsave(&dwc->lock, flags);
 510        val = dwc3_core_fifo_space(dep, DWC3_TXFIFOQ);
 511        seq_printf(s, "%u\n", val);
 512        spin_unlock_irqrestore(&dwc->lock, flags);
 513
 514        return 0;
 515}
 516
 517static int dwc3_rx_fifo_queue_show(struct seq_file *s, void *unused)
 518{
 519        struct dwc3_ep          *dep = s->private;
 520        struct dwc3             *dwc = dep->dwc;
 521        unsigned long           flags;
 522        u32                     val;
 523
 524        spin_lock_irqsave(&dwc->lock, flags);
 525        val = dwc3_core_fifo_space(dep, DWC3_RXFIFOQ);
 526        seq_printf(s, "%u\n", val);
 527        spin_unlock_irqrestore(&dwc->lock, flags);
 528
 529        return 0;
 530}
 531
 532static int dwc3_tx_request_queue_show(struct seq_file *s, void *unused)
 533{
 534        struct dwc3_ep          *dep = s->private;
 535        struct dwc3             *dwc = dep->dwc;
 536        unsigned long           flags;
 537        u32                     val;
 538
 539        spin_lock_irqsave(&dwc->lock, flags);
 540        val = dwc3_core_fifo_space(dep, DWC3_TXREQQ);
 541        seq_printf(s, "%u\n", val);
 542        spin_unlock_irqrestore(&dwc->lock, flags);
 543
 544        return 0;
 545}
 546
 547static int dwc3_rx_request_queue_show(struct seq_file *s, void *unused)
 548{
 549        struct dwc3_ep          *dep = s->private;
 550        struct dwc3             *dwc = dep->dwc;
 551        unsigned long           flags;
 552        u32                     val;
 553
 554        spin_lock_irqsave(&dwc->lock, flags);
 555        val = dwc3_core_fifo_space(dep, DWC3_RXREQQ);
 556        seq_printf(s, "%u\n", val);
 557        spin_unlock_irqrestore(&dwc->lock, flags);
 558
 559        return 0;
 560}
 561
 562static int dwc3_rx_info_queue_show(struct seq_file *s, void *unused)
 563{
 564        struct dwc3_ep          *dep = s->private;
 565        struct dwc3             *dwc = dep->dwc;
 566        unsigned long           flags;
 567        u32                     val;
 568
 569        spin_lock_irqsave(&dwc->lock, flags);
 570        val = dwc3_core_fifo_space(dep, DWC3_RXINFOQ);
 571        seq_printf(s, "%u\n", val);
 572        spin_unlock_irqrestore(&dwc->lock, flags);
 573
 574        return 0;
 575}
 576
 577static int dwc3_descriptor_fetch_queue_show(struct seq_file *s, void *unused)
 578{
 579        struct dwc3_ep          *dep = s->private;
 580        struct dwc3             *dwc = dep->dwc;
 581        unsigned long           flags;
 582        u32                     val;
 583
 584        spin_lock_irqsave(&dwc->lock, flags);
 585        val = dwc3_core_fifo_space(dep, DWC3_DESCFETCHQ);
 586        seq_printf(s, "%u\n", val);
 587        spin_unlock_irqrestore(&dwc->lock, flags);
 588
 589        return 0;
 590}
 591
 592static int dwc3_event_queue_show(struct seq_file *s, void *unused)
 593{
 594        struct dwc3_ep          *dep = s->private;
 595        struct dwc3             *dwc = dep->dwc;
 596        unsigned long           flags;
 597        u32                     val;
 598
 599        spin_lock_irqsave(&dwc->lock, flags);
 600        val = dwc3_core_fifo_space(dep, DWC3_EVENTQ);
 601        seq_printf(s, "%u\n", val);
 602        spin_unlock_irqrestore(&dwc->lock, flags);
 603
 604        return 0;
 605}
 606
 607static int dwc3_ep_transfer_type_show(struct seq_file *s, void *unused)
 608{
 609        struct dwc3_ep          *dep = s->private;
 610        struct dwc3             *dwc = dep->dwc;
 611        unsigned long           flags;
 612
 613        spin_lock_irqsave(&dwc->lock, flags);
 614        if (!(dep->flags & DWC3_EP_ENABLED) ||
 615                        !dep->endpoint.desc) {
 616                seq_printf(s, "--\n");
 617                goto out;
 618        }
 619
 620        switch (usb_endpoint_type(dep->endpoint.desc)) {
 621        case USB_ENDPOINT_XFER_CONTROL:
 622                seq_printf(s, "control\n");
 623                break;
 624        case USB_ENDPOINT_XFER_ISOC:
 625                seq_printf(s, "isochronous\n");
 626                break;
 627        case USB_ENDPOINT_XFER_BULK:
 628                seq_printf(s, "bulk\n");
 629                break;
 630        case USB_ENDPOINT_XFER_INT:
 631                seq_printf(s, "interrupt\n");
 632                break;
 633        default:
 634                seq_printf(s, "--\n");
 635        }
 636
 637out:
 638        spin_unlock_irqrestore(&dwc->lock, flags);
 639
 640        return 0;
 641}
 642
 643static int dwc3_ep_trb_ring_show(struct seq_file *s, void *unused)
 644{
 645        struct dwc3_ep          *dep = s->private;
 646        struct dwc3             *dwc = dep->dwc;
 647        unsigned long           flags;
 648        int                     i;
 649
 650        spin_lock_irqsave(&dwc->lock, flags);
 651        if (dep->number <= 1) {
 652                seq_printf(s, "--\n");
 653                goto out;
 654        }
 655
 656        seq_printf(s, "buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo\n");
 657
 658        for (i = 0; i < DWC3_TRB_NUM; i++) {
 659                struct dwc3_trb *trb = &dep->trb_pool[i];
 660                unsigned int type = DWC3_TRBCTL_TYPE(trb->ctrl);
 661
 662                seq_printf(s, "%08x%08x,%d,%s,%d,%d,%d,%d,%d,%d       %c%c\n",
 663                                trb->bph, trb->bpl, trb->size,
 664                                dwc3_trb_type_string(type),
 665                                !!(trb->ctrl & DWC3_TRB_CTRL_IOC),
 666                                !!(trb->ctrl & DWC3_TRB_CTRL_ISP_IMI),
 667                                !!(trb->ctrl & DWC3_TRB_CTRL_CSP),
 668                                !!(trb->ctrl & DWC3_TRB_CTRL_CHN),
 669                                !!(trb->ctrl & DWC3_TRB_CTRL_LST),
 670                                !!(trb->ctrl & DWC3_TRB_CTRL_HWO),
 671                                dep->trb_enqueue == i ? 'E' : ' ',
 672                                dep->trb_dequeue == i ? 'D' : ' ');
 673        }
 674
 675out:
 676        spin_unlock_irqrestore(&dwc->lock, flags);
 677
 678        return 0;
 679}
 680
 681static struct dwc3_ep_file_map map[] = {
 682        { "tx_fifo_queue", dwc3_tx_fifo_queue_show, },
 683        { "rx_fifo_queue", dwc3_rx_fifo_queue_show, },
 684        { "tx_request_queue", dwc3_tx_request_queue_show, },
 685        { "rx_request_queue", dwc3_rx_request_queue_show, },
 686        { "rx_info_queue", dwc3_rx_info_queue_show, },
 687        { "descriptor_fetch_queue", dwc3_descriptor_fetch_queue_show, },
 688        { "event_queue", dwc3_event_queue_show, },
 689        { "transfer_type", dwc3_ep_transfer_type_show, },
 690        { "trb_ring", dwc3_ep_trb_ring_show, },
 691};
 692
 693static int dwc3_endpoint_open(struct inode *inode, struct file *file)
 694{
 695        const char              *file_name = file_dentry(file)->d_iname;
 696        struct dwc3_ep_file_map *f_map;
 697        int                     i;
 698
 699        for (i = 0; i < ARRAY_SIZE(map); i++) {
 700                f_map = &map[i];
 701
 702                if (strcmp(f_map->name, file_name) == 0)
 703                        break;
 704        }
 705
 706        return single_open(file, f_map->show, inode->i_private);
 707}
 708
 709static const struct file_operations dwc3_endpoint_fops = {
 710        .open                   = dwc3_endpoint_open,
 711        .read                   = seq_read,
 712        .llseek                 = seq_lseek,
 713        .release                = single_release,
 714};
 715
 716static void dwc3_debugfs_create_endpoint_file(struct dwc3_ep *dep,
 717                struct dentry *parent, int type)
 718{
 719        struct dentry           *file;
 720        struct dwc3_ep_file_map *ep_file = &map[type];
 721
 722        file = debugfs_create_file(ep_file->name, S_IRUGO, parent, dep,
 723                        &dwc3_endpoint_fops);
 724}
 725
 726static void dwc3_debugfs_create_endpoint_files(struct dwc3_ep *dep,
 727                struct dentry *parent)
 728{
 729        int                     i;
 730
 731        for (i = 0; i < ARRAY_SIZE(map); i++)
 732                dwc3_debugfs_create_endpoint_file(dep, parent, i);
 733}
 734
 735static void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep,
 736                struct dentry *parent)
 737{
 738        struct dentry           *dir;
 739
 740        dir = debugfs_create_dir(dep->name, parent);
 741        if (IS_ERR_OR_NULL(dir))
 742                return;
 743
 744        dwc3_debugfs_create_endpoint_files(dep, dir);
 745}
 746
 747static void dwc3_debugfs_create_endpoint_dirs(struct dwc3 *dwc,
 748                struct dentry *parent)
 749{
 750        int                     i;
 751
 752        for (i = 0; i < dwc->num_eps; i++) {
 753                struct dwc3_ep  *dep = dwc->eps[i];
 754
 755                if (!dep)
 756                        continue;
 757
 758                dwc3_debugfs_create_endpoint_dir(dep, parent);
 759        }
 760}
 761
 762void dwc3_debugfs_init(struct dwc3 *dwc)
 763{
 764        struct dentry           *root;
 765        struct dentry           *file;
 766
 767        root = debugfs_create_dir(dev_name(dwc->dev), NULL);
 768        if (IS_ERR_OR_NULL(root)) {
 769                if (!root)
 770                        dev_err(dwc->dev, "Can't create debugfs root\n");
 771                return;
 772        }
 773        dwc->root = root;
 774
 775        dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL);
 776        if (!dwc->regset) {
 777                debugfs_remove_recursive(root);
 778                return;
 779        }
 780
 781        dwc->regset->regs = dwc3_regs;
 782        dwc->regset->nregs = ARRAY_SIZE(dwc3_regs);
 783        dwc->regset->base = dwc->regs - DWC3_GLOBALS_REGS_START;
 784
 785        file = debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset);
 786        if (!file)
 787                dev_dbg(dwc->dev, "Can't create debugfs regdump\n");
 788
 789        if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) {
 790                file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root,
 791                                dwc, &dwc3_mode_fops);
 792                if (!file)
 793                        dev_dbg(dwc->dev, "Can't create debugfs mode\n");
 794        }
 795
 796        if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) ||
 797                        IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
 798                file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root,
 799                                dwc, &dwc3_testmode_fops);
 800                if (!file)
 801                        dev_dbg(dwc->dev, "Can't create debugfs testmode\n");
 802
 803                file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR,
 804                                root, dwc, &dwc3_link_state_fops);
 805                if (!file)
 806                        dev_dbg(dwc->dev, "Can't create debugfs link_state\n");
 807
 808                dwc3_debugfs_create_endpoint_dirs(dwc, root);
 809        }
 810}
 811
 812void dwc3_debugfs_exit(struct dwc3 *dwc)
 813{
 814        debugfs_remove_recursive(dwc->root);
 815        kfree(dwc->regset);
 816}
 817