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 * Redistribution and use in source and binary forms, with or without
  10 * modification, are permitted provided that the following conditions
  11 * are met:
  12 * 1. Redistributions of source code must retain the above copyright
  13 *    notice, this list of conditions, and the following disclaimer,
  14 *    without modification.
  15 * 2. Redistributions in binary form must reproduce the above copyright
  16 *    notice, this list of conditions and the following disclaimer in the
  17 *    documentation and/or other materials provided with the distribution.
  18 * 3. The names of the above-listed copyright holders may not be used
  19 *    to endorse or promote products derived from this software without
  20 *    specific prior written permission.
  21 *
  22 * ALTERNATIVELY, this software may be distributed under the terms of the
  23 * GNU General Public License ("GPL") version 2, as published by the Free
  24 * Software Foundation.
  25 *
  26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  27 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  28 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  30 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  31 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  32 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  33 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  34 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  35 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37 */
  38
  39#include <linux/kernel.h>
  40#include <linux/slab.h>
  41#include <linux/ptrace.h>
  42#include <linux/types.h>
  43#include <linux/spinlock.h>
  44#include <linux/debugfs.h>
  45#include <linux/seq_file.h>
  46#include <linux/delay.h>
  47#include <linux/uaccess.h>
  48
  49#include <linux/usb/ch9.h>
  50
  51#include "core.h"
  52#include "gadget.h"
  53#include "io.h"
  54#include "debug.h"
  55
  56#define dump_register(nm)                               \
  57{                                                       \
  58        .name   = __stringify(nm),                      \
  59        .offset = DWC3_ ##nm - DWC3_GLOBALS_REGS_START, \
  60}
  61
  62static const struct debugfs_reg32 dwc3_regs[] = {
  63        dump_register(GSBUSCFG0),
  64        dump_register(GSBUSCFG1),
  65        dump_register(GTXTHRCFG),
  66        dump_register(GRXTHRCFG),
  67        dump_register(GCTL),
  68        dump_register(GEVTEN),
  69        dump_register(GSTS),
  70        dump_register(GSNPSID),
  71        dump_register(GGPIO),
  72        dump_register(GUID),
  73        dump_register(GUCTL),
  74        dump_register(GBUSERRADDR0),
  75        dump_register(GBUSERRADDR1),
  76        dump_register(GPRTBIMAP0),
  77        dump_register(GPRTBIMAP1),
  78        dump_register(GHWPARAMS0),
  79        dump_register(GHWPARAMS1),
  80        dump_register(GHWPARAMS2),
  81        dump_register(GHWPARAMS3),
  82        dump_register(GHWPARAMS4),
  83        dump_register(GHWPARAMS5),
  84        dump_register(GHWPARAMS6),
  85        dump_register(GHWPARAMS7),
  86        dump_register(GDBGFIFOSPACE),
  87        dump_register(GDBGLTSSM),
  88        dump_register(GPRTBIMAP_HS0),
  89        dump_register(GPRTBIMAP_HS1),
  90        dump_register(GPRTBIMAP_FS0),
  91        dump_register(GPRTBIMAP_FS1),
  92
  93        dump_register(GUSB2PHYCFG(0)),
  94        dump_register(GUSB2PHYCFG(1)),
  95        dump_register(GUSB2PHYCFG(2)),
  96        dump_register(GUSB2PHYCFG(3)),
  97        dump_register(GUSB2PHYCFG(4)),
  98        dump_register(GUSB2PHYCFG(5)),
  99        dump_register(GUSB2PHYCFG(6)),
 100        dump_register(GUSB2PHYCFG(7)),
 101        dump_register(GUSB2PHYCFG(8)),
 102        dump_register(GUSB2PHYCFG(9)),
 103        dump_register(GUSB2PHYCFG(10)),
 104        dump_register(GUSB2PHYCFG(11)),
 105        dump_register(GUSB2PHYCFG(12)),
 106        dump_register(GUSB2PHYCFG(13)),
 107        dump_register(GUSB2PHYCFG(14)),
 108        dump_register(GUSB2PHYCFG(15)),
 109
 110        dump_register(GUSB2I2CCTL(0)),
 111        dump_register(GUSB2I2CCTL(1)),
 112        dump_register(GUSB2I2CCTL(2)),
 113        dump_register(GUSB2I2CCTL(3)),
 114        dump_register(GUSB2I2CCTL(4)),
 115        dump_register(GUSB2I2CCTL(5)),
 116        dump_register(GUSB2I2CCTL(6)),
 117        dump_register(GUSB2I2CCTL(7)),
 118        dump_register(GUSB2I2CCTL(8)),
 119        dump_register(GUSB2I2CCTL(9)),
 120        dump_register(GUSB2I2CCTL(10)),
 121        dump_register(GUSB2I2CCTL(11)),
 122        dump_register(GUSB2I2CCTL(12)),
 123        dump_register(GUSB2I2CCTL(13)),
 124        dump_register(GUSB2I2CCTL(14)),
 125        dump_register(GUSB2I2CCTL(15)),
 126
 127        dump_register(GUSB2PHYACC(0)),
 128        dump_register(GUSB2PHYACC(1)),
 129        dump_register(GUSB2PHYACC(2)),
 130        dump_register(GUSB2PHYACC(3)),
 131        dump_register(GUSB2PHYACC(4)),
 132        dump_register(GUSB2PHYACC(5)),
 133        dump_register(GUSB2PHYACC(6)),
 134        dump_register(GUSB2PHYACC(7)),
 135        dump_register(GUSB2PHYACC(8)),
 136        dump_register(GUSB2PHYACC(9)),
 137        dump_register(GUSB2PHYACC(10)),
 138        dump_register(GUSB2PHYACC(11)),
 139        dump_register(GUSB2PHYACC(12)),
 140        dump_register(GUSB2PHYACC(13)),
 141        dump_register(GUSB2PHYACC(14)),
 142        dump_register(GUSB2PHYACC(15)),
 143
 144        dump_register(GUSB3PIPECTL(0)),
 145        dump_register(GUSB3PIPECTL(1)),
 146        dump_register(GUSB3PIPECTL(2)),
 147        dump_register(GUSB3PIPECTL(3)),
 148        dump_register(GUSB3PIPECTL(4)),
 149        dump_register(GUSB3PIPECTL(5)),
 150        dump_register(GUSB3PIPECTL(6)),
 151        dump_register(GUSB3PIPECTL(7)),
 152        dump_register(GUSB3PIPECTL(8)),
 153        dump_register(GUSB3PIPECTL(9)),
 154        dump_register(GUSB3PIPECTL(10)),
 155        dump_register(GUSB3PIPECTL(11)),
 156        dump_register(GUSB3PIPECTL(12)),
 157        dump_register(GUSB3PIPECTL(13)),
 158        dump_register(GUSB3PIPECTL(14)),
 159        dump_register(GUSB3PIPECTL(15)),
 160
 161        dump_register(GTXFIFOSIZ(0)),
 162        dump_register(GTXFIFOSIZ(1)),
 163        dump_register(GTXFIFOSIZ(2)),
 164        dump_register(GTXFIFOSIZ(3)),
 165        dump_register(GTXFIFOSIZ(4)),
 166        dump_register(GTXFIFOSIZ(5)),
 167        dump_register(GTXFIFOSIZ(6)),
 168        dump_register(GTXFIFOSIZ(7)),
 169        dump_register(GTXFIFOSIZ(8)),
 170        dump_register(GTXFIFOSIZ(9)),
 171        dump_register(GTXFIFOSIZ(10)),
 172        dump_register(GTXFIFOSIZ(11)),
 173        dump_register(GTXFIFOSIZ(12)),
 174        dump_register(GTXFIFOSIZ(13)),
 175        dump_register(GTXFIFOSIZ(14)),
 176        dump_register(GTXFIFOSIZ(15)),
 177        dump_register(GTXFIFOSIZ(16)),
 178        dump_register(GTXFIFOSIZ(17)),
 179        dump_register(GTXFIFOSIZ(18)),
 180        dump_register(GTXFIFOSIZ(19)),
 181        dump_register(GTXFIFOSIZ(20)),
 182        dump_register(GTXFIFOSIZ(21)),
 183        dump_register(GTXFIFOSIZ(22)),
 184        dump_register(GTXFIFOSIZ(23)),
 185        dump_register(GTXFIFOSIZ(24)),
 186        dump_register(GTXFIFOSIZ(25)),
 187        dump_register(GTXFIFOSIZ(26)),
 188        dump_register(GTXFIFOSIZ(27)),
 189        dump_register(GTXFIFOSIZ(28)),
 190        dump_register(GTXFIFOSIZ(29)),
 191        dump_register(GTXFIFOSIZ(30)),
 192        dump_register(GTXFIFOSIZ(31)),
 193
 194        dump_register(GRXFIFOSIZ(0)),
 195        dump_register(GRXFIFOSIZ(1)),
 196        dump_register(GRXFIFOSIZ(2)),
 197        dump_register(GRXFIFOSIZ(3)),
 198        dump_register(GRXFIFOSIZ(4)),
 199        dump_register(GRXFIFOSIZ(5)),
 200        dump_register(GRXFIFOSIZ(6)),
 201        dump_register(GRXFIFOSIZ(7)),
 202        dump_register(GRXFIFOSIZ(8)),
 203        dump_register(GRXFIFOSIZ(9)),
 204        dump_register(GRXFIFOSIZ(10)),
 205        dump_register(GRXFIFOSIZ(11)),
 206        dump_register(GRXFIFOSIZ(12)),
 207        dump_register(GRXFIFOSIZ(13)),
 208        dump_register(GRXFIFOSIZ(14)),
 209        dump_register(GRXFIFOSIZ(15)),
 210        dump_register(GRXFIFOSIZ(16)),
 211        dump_register(GRXFIFOSIZ(17)),
 212        dump_register(GRXFIFOSIZ(18)),
 213        dump_register(GRXFIFOSIZ(19)),
 214        dump_register(GRXFIFOSIZ(20)),
 215        dump_register(GRXFIFOSIZ(21)),
 216        dump_register(GRXFIFOSIZ(22)),
 217        dump_register(GRXFIFOSIZ(23)),
 218        dump_register(GRXFIFOSIZ(24)),
 219        dump_register(GRXFIFOSIZ(25)),
 220        dump_register(GRXFIFOSIZ(26)),
 221        dump_register(GRXFIFOSIZ(27)),
 222        dump_register(GRXFIFOSIZ(28)),
 223        dump_register(GRXFIFOSIZ(29)),
 224        dump_register(GRXFIFOSIZ(30)),
 225        dump_register(GRXFIFOSIZ(31)),
 226
 227        dump_register(GEVNTADRLO(0)),
 228        dump_register(GEVNTADRHI(0)),
 229        dump_register(GEVNTSIZ(0)),
 230        dump_register(GEVNTCOUNT(0)),
 231
 232        dump_register(GHWPARAMS8),
 233        dump_register(DCFG),
 234        dump_register(DCTL),
 235        dump_register(DEVTEN),
 236        dump_register(DSTS),
 237        dump_register(DGCMDPAR),
 238        dump_register(DGCMD),
 239        dump_register(DALEPENA),
 240
 241        dump_register(DEPCMDPAR2(0)),
 242        dump_register(DEPCMDPAR2(1)),
 243        dump_register(DEPCMDPAR2(2)),
 244        dump_register(DEPCMDPAR2(3)),
 245        dump_register(DEPCMDPAR2(4)),
 246        dump_register(DEPCMDPAR2(5)),
 247        dump_register(DEPCMDPAR2(6)),
 248        dump_register(DEPCMDPAR2(7)),
 249        dump_register(DEPCMDPAR2(8)),
 250        dump_register(DEPCMDPAR2(9)),
 251        dump_register(DEPCMDPAR2(10)),
 252        dump_register(DEPCMDPAR2(11)),
 253        dump_register(DEPCMDPAR2(12)),
 254        dump_register(DEPCMDPAR2(13)),
 255        dump_register(DEPCMDPAR2(14)),
 256        dump_register(DEPCMDPAR2(15)),
 257        dump_register(DEPCMDPAR2(16)),
 258        dump_register(DEPCMDPAR2(17)),
 259        dump_register(DEPCMDPAR2(18)),
 260        dump_register(DEPCMDPAR2(19)),
 261        dump_register(DEPCMDPAR2(20)),
 262        dump_register(DEPCMDPAR2(21)),
 263        dump_register(DEPCMDPAR2(22)),
 264        dump_register(DEPCMDPAR2(23)),
 265        dump_register(DEPCMDPAR2(24)),
 266        dump_register(DEPCMDPAR2(25)),
 267        dump_register(DEPCMDPAR2(26)),
 268        dump_register(DEPCMDPAR2(27)),
 269        dump_register(DEPCMDPAR2(28)),
 270        dump_register(DEPCMDPAR2(29)),
 271        dump_register(DEPCMDPAR2(30)),
 272        dump_register(DEPCMDPAR2(31)),
 273
 274        dump_register(DEPCMDPAR1(0)),
 275        dump_register(DEPCMDPAR1(1)),
 276        dump_register(DEPCMDPAR1(2)),
 277        dump_register(DEPCMDPAR1(3)),
 278        dump_register(DEPCMDPAR1(4)),
 279        dump_register(DEPCMDPAR1(5)),
 280        dump_register(DEPCMDPAR1(6)),
 281        dump_register(DEPCMDPAR1(7)),
 282        dump_register(DEPCMDPAR1(8)),
 283        dump_register(DEPCMDPAR1(9)),
 284        dump_register(DEPCMDPAR1(10)),
 285        dump_register(DEPCMDPAR1(11)),
 286        dump_register(DEPCMDPAR1(12)),
 287        dump_register(DEPCMDPAR1(13)),
 288        dump_register(DEPCMDPAR1(14)),
 289        dump_register(DEPCMDPAR1(15)),
 290        dump_register(DEPCMDPAR1(16)),
 291        dump_register(DEPCMDPAR1(17)),
 292        dump_register(DEPCMDPAR1(18)),
 293        dump_register(DEPCMDPAR1(19)),
 294        dump_register(DEPCMDPAR1(20)),
 295        dump_register(DEPCMDPAR1(21)),
 296        dump_register(DEPCMDPAR1(22)),
 297        dump_register(DEPCMDPAR1(23)),
 298        dump_register(DEPCMDPAR1(24)),
 299        dump_register(DEPCMDPAR1(25)),
 300        dump_register(DEPCMDPAR1(26)),
 301        dump_register(DEPCMDPAR1(27)),
 302        dump_register(DEPCMDPAR1(28)),
 303        dump_register(DEPCMDPAR1(29)),
 304        dump_register(DEPCMDPAR1(30)),
 305        dump_register(DEPCMDPAR1(31)),
 306
 307        dump_register(DEPCMDPAR0(0)),
 308        dump_register(DEPCMDPAR0(1)),
 309        dump_register(DEPCMDPAR0(2)),
 310        dump_register(DEPCMDPAR0(3)),
 311        dump_register(DEPCMDPAR0(4)),
 312        dump_register(DEPCMDPAR0(5)),
 313        dump_register(DEPCMDPAR0(6)),
 314        dump_register(DEPCMDPAR0(7)),
 315        dump_register(DEPCMDPAR0(8)),
 316        dump_register(DEPCMDPAR0(9)),
 317        dump_register(DEPCMDPAR0(10)),
 318        dump_register(DEPCMDPAR0(11)),
 319        dump_register(DEPCMDPAR0(12)),
 320        dump_register(DEPCMDPAR0(13)),
 321        dump_register(DEPCMDPAR0(14)),
 322        dump_register(DEPCMDPAR0(15)),
 323        dump_register(DEPCMDPAR0(16)),
 324        dump_register(DEPCMDPAR0(17)),
 325        dump_register(DEPCMDPAR0(18)),
 326        dump_register(DEPCMDPAR0(19)),
 327        dump_register(DEPCMDPAR0(20)),
 328        dump_register(DEPCMDPAR0(21)),
 329        dump_register(DEPCMDPAR0(22)),
 330        dump_register(DEPCMDPAR0(23)),
 331        dump_register(DEPCMDPAR0(24)),
 332        dump_register(DEPCMDPAR0(25)),
 333        dump_register(DEPCMDPAR0(26)),
 334        dump_register(DEPCMDPAR0(27)),
 335        dump_register(DEPCMDPAR0(28)),
 336        dump_register(DEPCMDPAR0(29)),
 337        dump_register(DEPCMDPAR0(30)),
 338        dump_register(DEPCMDPAR0(31)),
 339
 340        dump_register(DEPCMD(0)),
 341        dump_register(DEPCMD(1)),
 342        dump_register(DEPCMD(2)),
 343        dump_register(DEPCMD(3)),
 344        dump_register(DEPCMD(4)),
 345        dump_register(DEPCMD(5)),
 346        dump_register(DEPCMD(6)),
 347        dump_register(DEPCMD(7)),
 348        dump_register(DEPCMD(8)),
 349        dump_register(DEPCMD(9)),
 350        dump_register(DEPCMD(10)),
 351        dump_register(DEPCMD(11)),
 352        dump_register(DEPCMD(12)),
 353        dump_register(DEPCMD(13)),
 354        dump_register(DEPCMD(14)),
 355        dump_register(DEPCMD(15)),
 356        dump_register(DEPCMD(16)),
 357        dump_register(DEPCMD(17)),
 358        dump_register(DEPCMD(18)),
 359        dump_register(DEPCMD(19)),
 360        dump_register(DEPCMD(20)),
 361        dump_register(DEPCMD(21)),
 362        dump_register(DEPCMD(22)),
 363        dump_register(DEPCMD(23)),
 364        dump_register(DEPCMD(24)),
 365        dump_register(DEPCMD(25)),
 366        dump_register(DEPCMD(26)),
 367        dump_register(DEPCMD(27)),
 368        dump_register(DEPCMD(28)),
 369        dump_register(DEPCMD(29)),
 370        dump_register(DEPCMD(30)),
 371        dump_register(DEPCMD(31)),
 372
 373        dump_register(OCFG),
 374        dump_register(OCTL),
 375        dump_register(OEVT),
 376        dump_register(OEVTEN),
 377        dump_register(OSTS),
 378};
 379
 380static int dwc3_mode_show(struct seq_file *s, void *unused)
 381{
 382        struct dwc3             *dwc = s->private;
 383        unsigned long           flags;
 384        u32                     reg;
 385
 386        spin_lock_irqsave(&dwc->lock, flags);
 387        reg = dwc3_readl(dwc->regs, DWC3_GCTL);
 388        spin_unlock_irqrestore(&dwc->lock, flags);
 389
 390        switch (DWC3_GCTL_PRTCAP(reg)) {
 391        case DWC3_GCTL_PRTCAP_HOST:
 392                seq_printf(s, "host\n");
 393                break;
 394        case DWC3_GCTL_PRTCAP_DEVICE:
 395                seq_printf(s, "device\n");
 396                break;
 397        case DWC3_GCTL_PRTCAP_OTG:
 398                seq_printf(s, "OTG\n");
 399                break;
 400        default:
 401                seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg));
 402        }
 403
 404        return 0;
 405}
 406
 407static int dwc3_mode_open(struct inode *inode, struct file *file)
 408{
 409        return single_open(file, dwc3_mode_show, inode->i_private);
 410}
 411
 412static ssize_t dwc3_mode_write(struct file *file,
 413                const char __user *ubuf, size_t count, loff_t *ppos)
 414{
 415        struct seq_file         *s = file->private_data;
 416        struct dwc3             *dwc = s->private;
 417        unsigned long           flags;
 418        u32                     mode = 0;
 419        char                    buf[32];
 420
 421        if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
 422                return -EFAULT;
 423
 424        if (!strncmp(buf, "host", 4))
 425                mode |= DWC3_GCTL_PRTCAP_HOST;
 426
 427        if (!strncmp(buf, "device", 6))
 428                mode |= DWC3_GCTL_PRTCAP_DEVICE;
 429
 430        if (!strncmp(buf, "otg", 3))
 431                mode |= DWC3_GCTL_PRTCAP_OTG;
 432
 433        if (mode) {
 434                spin_lock_irqsave(&dwc->lock, flags);
 435                dwc3_set_mode(dwc, mode);
 436                spin_unlock_irqrestore(&dwc->lock, flags);
 437        }
 438        return count;
 439}
 440
 441static const struct file_operations dwc3_mode_fops = {
 442        .open                   = dwc3_mode_open,
 443        .write                  = dwc3_mode_write,
 444        .read                   = seq_read,
 445        .llseek                 = seq_lseek,
 446        .release                = single_release,
 447};
 448
 449static int dwc3_testmode_show(struct seq_file *s, void *unused)
 450{
 451        struct dwc3             *dwc = s->private;
 452        unsigned long           flags;
 453        u32                     reg;
 454
 455        spin_lock_irqsave(&dwc->lock, flags);
 456        reg = dwc3_readl(dwc->regs, DWC3_DCTL);
 457        reg &= DWC3_DCTL_TSTCTRL_MASK;
 458        reg >>= 1;
 459        spin_unlock_irqrestore(&dwc->lock, flags);
 460
 461        switch (reg) {
 462        case 0:
 463                seq_printf(s, "no test\n");
 464                break;
 465        case TEST_J:
 466                seq_printf(s, "test_j\n");
 467                break;
 468        case TEST_K:
 469                seq_printf(s, "test_k\n");
 470                break;
 471        case TEST_SE0_NAK:
 472                seq_printf(s, "test_se0_nak\n");
 473                break;
 474        case TEST_PACKET:
 475                seq_printf(s, "test_packet\n");
 476                break;
 477        case TEST_FORCE_EN:
 478                seq_printf(s, "test_force_enable\n");
 479                break;
 480        default:
 481                seq_printf(s, "UNKNOWN %d\n", reg);
 482        }
 483
 484        return 0;
 485}
 486
 487static int dwc3_testmode_open(struct inode *inode, struct file *file)
 488{
 489        return single_open(file, dwc3_testmode_show, inode->i_private);
 490}
 491
 492static ssize_t dwc3_testmode_write(struct file *file,
 493                const char __user *ubuf, size_t count, loff_t *ppos)
 494{
 495        struct seq_file         *s = file->private_data;
 496        struct dwc3             *dwc = s->private;
 497        unsigned long           flags;
 498        u32                     testmode = 0;
 499        char                    buf[32];
 500
 501        if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
 502                return -EFAULT;
 503
 504        if (!strncmp(buf, "test_j", 6))
 505                testmode = TEST_J;
 506        else if (!strncmp(buf, "test_k", 6))
 507                testmode = TEST_K;
 508        else if (!strncmp(buf, "test_se0_nak", 12))
 509                testmode = TEST_SE0_NAK;
 510        else if (!strncmp(buf, "test_packet", 11))
 511                testmode = TEST_PACKET;
 512        else if (!strncmp(buf, "test_force_enable", 17))
 513                testmode = TEST_FORCE_EN;
 514        else
 515                testmode = 0;
 516
 517        spin_lock_irqsave(&dwc->lock, flags);
 518        dwc3_gadget_set_test_mode(dwc, testmode);
 519        spin_unlock_irqrestore(&dwc->lock, flags);
 520
 521        return count;
 522}
 523
 524static const struct file_operations dwc3_testmode_fops = {
 525        .open                   = dwc3_testmode_open,
 526        .write                  = dwc3_testmode_write,
 527        .read                   = seq_read,
 528        .llseek                 = seq_lseek,
 529        .release                = single_release,
 530};
 531
 532static int dwc3_link_state_show(struct seq_file *s, void *unused)
 533{
 534        struct dwc3             *dwc = s->private;
 535        unsigned long           flags;
 536        enum dwc3_link_state    state;
 537        u32                     reg;
 538
 539        spin_lock_irqsave(&dwc->lock, flags);
 540        reg = dwc3_readl(dwc->regs, DWC3_DSTS);
 541        state = DWC3_DSTS_USBLNKST(reg);
 542        spin_unlock_irqrestore(&dwc->lock, flags);
 543
 544        switch (state) {
 545        case DWC3_LINK_STATE_U0:
 546                seq_printf(s, "U0\n");
 547                break;
 548        case DWC3_LINK_STATE_U1:
 549                seq_printf(s, "U1\n");
 550                break;
 551        case DWC3_LINK_STATE_U2:
 552                seq_printf(s, "U2\n");
 553                break;
 554        case DWC3_LINK_STATE_U3:
 555                seq_printf(s, "U3\n");
 556                break;
 557        case DWC3_LINK_STATE_SS_DIS:
 558                seq_printf(s, "SS.Disabled\n");
 559                break;
 560        case DWC3_LINK_STATE_RX_DET:
 561                seq_printf(s, "Rx.Detect\n");
 562                break;
 563        case DWC3_LINK_STATE_SS_INACT:
 564                seq_printf(s, "SS.Inactive\n");
 565                break;
 566        case DWC3_LINK_STATE_POLL:
 567                seq_printf(s, "Poll\n");
 568                break;
 569        case DWC3_LINK_STATE_RECOV:
 570                seq_printf(s, "Recovery\n");
 571                break;
 572        case DWC3_LINK_STATE_HRESET:
 573                seq_printf(s, "HRESET\n");
 574                break;
 575        case DWC3_LINK_STATE_CMPLY:
 576                seq_printf(s, "Compliance\n");
 577                break;
 578        case DWC3_LINK_STATE_LPBK:
 579                seq_printf(s, "Loopback\n");
 580                break;
 581        case DWC3_LINK_STATE_RESET:
 582                seq_printf(s, "Reset\n");
 583                break;
 584        case DWC3_LINK_STATE_RESUME:
 585                seq_printf(s, "Resume\n");
 586                break;
 587        default:
 588                seq_printf(s, "UNKNOWN %d\n", state);
 589        }
 590
 591        return 0;
 592}
 593
 594static int dwc3_link_state_open(struct inode *inode, struct file *file)
 595{
 596        return single_open(file, dwc3_link_state_show, inode->i_private);
 597}
 598
 599static ssize_t dwc3_link_state_write(struct file *file,
 600                const char __user *ubuf, size_t count, loff_t *ppos)
 601{
 602        struct seq_file         *s = file->private_data;
 603        struct dwc3             *dwc = s->private;
 604        unsigned long           flags;
 605        enum dwc3_link_state    state = 0;
 606        char                    buf[32];
 607
 608        if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
 609                return -EFAULT;
 610
 611        if (!strncmp(buf, "SS.Disabled", 11))
 612                state = DWC3_LINK_STATE_SS_DIS;
 613        else if (!strncmp(buf, "Rx.Detect", 9))
 614                state = DWC3_LINK_STATE_RX_DET;
 615        else if (!strncmp(buf, "SS.Inactive", 11))
 616                state = DWC3_LINK_STATE_SS_INACT;
 617        else if (!strncmp(buf, "Recovery", 8))
 618                state = DWC3_LINK_STATE_RECOV;
 619        else if (!strncmp(buf, "Compliance", 10))
 620                state = DWC3_LINK_STATE_CMPLY;
 621        else if (!strncmp(buf, "Loopback", 8))
 622                state = DWC3_LINK_STATE_LPBK;
 623        else
 624                return -EINVAL;
 625
 626        spin_lock_irqsave(&dwc->lock, flags);
 627        dwc3_gadget_set_link_state(dwc, state);
 628        spin_unlock_irqrestore(&dwc->lock, flags);
 629
 630        return count;
 631}
 632
 633static const struct file_operations dwc3_link_state_fops = {
 634        .open                   = dwc3_link_state_open,
 635        .write                  = dwc3_link_state_write,
 636        .read                   = seq_read,
 637        .llseek                 = seq_lseek,
 638        .release                = single_release,
 639};
 640
 641int dwc3_debugfs_init(struct dwc3 *dwc)
 642{
 643        struct dentry           *root;
 644        struct dentry           *file;
 645        int                     ret;
 646
 647        root = debugfs_create_dir(dev_name(dwc->dev), NULL);
 648        if (!root) {
 649                ret = -ENOMEM;
 650                goto err0;
 651        }
 652
 653        dwc->root = root;
 654
 655        dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL);
 656        if (!dwc->regset) {
 657                ret = -ENOMEM;
 658                goto err1;
 659        }
 660
 661        dwc->regset->regs = dwc3_regs;
 662        dwc->regset->nregs = ARRAY_SIZE(dwc3_regs);
 663        dwc->regset->base = dwc->regs;
 664
 665        file = debugfs_create_regset32("regdump", S_IRUGO, root, dwc->regset);
 666        if (!file) {
 667                ret = -ENOMEM;
 668                goto err1;
 669        }
 670
 671        if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)) {
 672                file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root,
 673                                dwc, &dwc3_mode_fops);
 674                if (!file) {
 675                        ret = -ENOMEM;
 676                        goto err1;
 677                }
 678        }
 679
 680        if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) ||
 681                        IS_ENABLED(CONFIG_USB_DWC3_GADGET)) {
 682                file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root,
 683                                dwc, &dwc3_testmode_fops);
 684                if (!file) {
 685                        ret = -ENOMEM;
 686                        goto err1;
 687                }
 688
 689                file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root,
 690                                dwc, &dwc3_link_state_fops);
 691                if (!file) {
 692                        ret = -ENOMEM;
 693                        goto err1;
 694                }
 695        }
 696
 697        return 0;
 698
 699err1:
 700        debugfs_remove_recursive(root);
 701
 702err0:
 703        return ret;
 704}
 705
 706void dwc3_debugfs_exit(struct dwc3 *dwc)
 707{
 708        debugfs_remove_recursive(dwc->root);
 709        dwc->root = NULL;
 710}
 711