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