diff options
Diffstat (limited to 'drivers/usb/dwc3/debugfs.c')
-rw-r--r-- | drivers/usb/dwc3/debugfs.c | 214 |
1 files changed, 208 insertions, 6 deletions
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 433c97c15fc5..d4a30f118724 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c | |||
@@ -46,6 +46,8 @@ | |||
46 | #include <linux/delay.h> | 46 | #include <linux/delay.h> |
47 | #include <linux/uaccess.h> | 47 | #include <linux/uaccess.h> |
48 | 48 | ||
49 | #include <linux/usb/ch9.h> | ||
50 | |||
49 | #include "core.h" | 51 | #include "core.h" |
50 | #include "gadget.h" | 52 | #include "gadget.h" |
51 | #include "io.h" | 53 | #include "io.h" |
@@ -464,6 +466,192 @@ static const struct file_operations dwc3_mode_fops = { | |||
464 | .release = single_release, | 466 | .release = single_release, |
465 | }; | 467 | }; |
466 | 468 | ||
469 | static int dwc3_testmode_show(struct seq_file *s, void *unused) | ||
470 | { | ||
471 | struct dwc3 *dwc = s->private; | ||
472 | unsigned long flags; | ||
473 | u32 reg; | ||
474 | |||
475 | spin_lock_irqsave(&dwc->lock, flags); | ||
476 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
477 | reg &= DWC3_DCTL_TSTCTRL_MASK; | ||
478 | reg >>= 1; | ||
479 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
480 | |||
481 | switch (reg) { | ||
482 | case 0: | ||
483 | seq_printf(s, "no test\n"); | ||
484 | break; | ||
485 | case TEST_J: | ||
486 | seq_printf(s, "test_j\n"); | ||
487 | break; | ||
488 | case TEST_K: | ||
489 | seq_printf(s, "test_k\n"); | ||
490 | break; | ||
491 | case TEST_SE0_NAK: | ||
492 | seq_printf(s, "test_se0_nak\n"); | ||
493 | break; | ||
494 | case TEST_PACKET: | ||
495 | seq_printf(s, "test_packet\n"); | ||
496 | break; | ||
497 | case TEST_FORCE_EN: | ||
498 | seq_printf(s, "test_force_enable\n"); | ||
499 | break; | ||
500 | default: | ||
501 | seq_printf(s, "UNKNOWN %d\n", reg); | ||
502 | } | ||
503 | |||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | static int dwc3_testmode_open(struct inode *inode, struct file *file) | ||
508 | { | ||
509 | return single_open(file, dwc3_testmode_show, inode->i_private); | ||
510 | } | ||
511 | |||
512 | static ssize_t dwc3_testmode_write(struct file *file, | ||
513 | const char __user *ubuf, size_t count, loff_t *ppos) | ||
514 | { | ||
515 | struct seq_file *s = file->private_data; | ||
516 | struct dwc3 *dwc = s->private; | ||
517 | unsigned long flags; | ||
518 | u32 testmode = 0; | ||
519 | char buf[32]; | ||
520 | |||
521 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
522 | return -EFAULT; | ||
523 | |||
524 | if (!strncmp(buf, "test_j", 6)) | ||
525 | testmode = TEST_J; | ||
526 | else if (!strncmp(buf, "test_k", 6)) | ||
527 | testmode = TEST_K; | ||
528 | else if (!strncmp(buf, "test_se0_nak", 12)) | ||
529 | testmode = TEST_SE0_NAK; | ||
530 | else if (!strncmp(buf, "test_packet", 11)) | ||
531 | testmode = TEST_PACKET; | ||
532 | else if (!strncmp(buf, "test_force_enable", 17)) | ||
533 | testmode = TEST_FORCE_EN; | ||
534 | else | ||
535 | testmode = 0; | ||
536 | |||
537 | spin_lock_irqsave(&dwc->lock, flags); | ||
538 | dwc3_gadget_set_test_mode(dwc, testmode); | ||
539 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
540 | |||
541 | return count; | ||
542 | } | ||
543 | |||
544 | static const struct file_operations dwc3_testmode_fops = { | ||
545 | .open = dwc3_testmode_open, | ||
546 | .write = dwc3_testmode_write, | ||
547 | .read = seq_read, | ||
548 | .llseek = seq_lseek, | ||
549 | .release = single_release, | ||
550 | }; | ||
551 | |||
552 | static int dwc3_link_state_show(struct seq_file *s, void *unused) | ||
553 | { | ||
554 | struct dwc3 *dwc = s->private; | ||
555 | unsigned long flags; | ||
556 | enum dwc3_link_state state; | ||
557 | u32 reg; | ||
558 | |||
559 | spin_lock_irqsave(&dwc->lock, flags); | ||
560 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | ||
561 | state = DWC3_DSTS_USBLNKST(reg); | ||
562 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
563 | |||
564 | switch (state) { | ||
565 | case DWC3_LINK_STATE_U0: | ||
566 | seq_printf(s, "U0\n"); | ||
567 | break; | ||
568 | case DWC3_LINK_STATE_U1: | ||
569 | seq_printf(s, "U1\n"); | ||
570 | break; | ||
571 | case DWC3_LINK_STATE_U2: | ||
572 | seq_printf(s, "U2\n"); | ||
573 | break; | ||
574 | case DWC3_LINK_STATE_U3: | ||
575 | seq_printf(s, "U3\n"); | ||
576 | break; | ||
577 | case DWC3_LINK_STATE_SS_DIS: | ||
578 | seq_printf(s, "SS.Disabled\n"); | ||
579 | break; | ||
580 | case DWC3_LINK_STATE_RX_DET: | ||
581 | seq_printf(s, "Rx.Detect\n"); | ||
582 | break; | ||
583 | case DWC3_LINK_STATE_SS_INACT: | ||
584 | seq_printf(s, "SS.Inactive\n"); | ||
585 | break; | ||
586 | case DWC3_LINK_STATE_POLL: | ||
587 | seq_printf(s, "Poll\n"); | ||
588 | break; | ||
589 | case DWC3_LINK_STATE_RECOV: | ||
590 | seq_printf(s, "Recovery\n"); | ||
591 | break; | ||
592 | case DWC3_LINK_STATE_HRESET: | ||
593 | seq_printf(s, "HRESET\n"); | ||
594 | break; | ||
595 | case DWC3_LINK_STATE_CMPLY: | ||
596 | seq_printf(s, "Compliance\n"); | ||
597 | break; | ||
598 | case DWC3_LINK_STATE_LPBK: | ||
599 | seq_printf(s, "Loopback\n"); | ||
600 | break; | ||
601 | default: | ||
602 | seq_printf(s, "UNKNOWN %d\n", reg); | ||
603 | } | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static int dwc3_link_state_open(struct inode *inode, struct file *file) | ||
609 | { | ||
610 | return single_open(file, dwc3_link_state_show, inode->i_private); | ||
611 | } | ||
612 | |||
613 | static ssize_t dwc3_link_state_write(struct file *file, | ||
614 | const char __user *ubuf, size_t count, loff_t *ppos) | ||
615 | { | ||
616 | struct seq_file *s = file->private_data; | ||
617 | struct dwc3 *dwc = s->private; | ||
618 | unsigned long flags; | ||
619 | enum dwc3_link_state state = 0; | ||
620 | char buf[32]; | ||
621 | |||
622 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
623 | return -EFAULT; | ||
624 | |||
625 | if (!strncmp(buf, "SS.Disabled", 11)) | ||
626 | state = DWC3_LINK_STATE_SS_DIS; | ||
627 | else if (!strncmp(buf, "Rx.Detect", 9)) | ||
628 | state = DWC3_LINK_STATE_RX_DET; | ||
629 | else if (!strncmp(buf, "SS.Inactive", 11)) | ||
630 | state = DWC3_LINK_STATE_SS_INACT; | ||
631 | else if (!strncmp(buf, "Recovery", 8)) | ||
632 | state = DWC3_LINK_STATE_RECOV; | ||
633 | else if (!strncmp(buf, "Compliance", 10)) | ||
634 | state = DWC3_LINK_STATE_CMPLY; | ||
635 | else if (!strncmp(buf, "Loopback", 8)) | ||
636 | state = DWC3_LINK_STATE_LPBK; | ||
637 | else | ||
638 | return -EINVAL; | ||
639 | |||
640 | spin_lock_irqsave(&dwc->lock, flags); | ||
641 | dwc3_gadget_set_link_state(dwc, state); | ||
642 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
643 | |||
644 | return count; | ||
645 | } | ||
646 | |||
647 | static const struct file_operations dwc3_link_state_fops = { | ||
648 | .open = dwc3_link_state_open, | ||
649 | .write = dwc3_link_state_write, | ||
650 | .read = seq_read, | ||
651 | .llseek = seq_lseek, | ||
652 | .release = single_release, | ||
653 | }; | ||
654 | |||
467 | int __devinit dwc3_debugfs_init(struct dwc3 *dwc) | 655 | int __devinit dwc3_debugfs_init(struct dwc3 *dwc) |
468 | { | 656 | { |
469 | struct dentry *root; | 657 | struct dentry *root; |
@@ -471,8 +659,8 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc) | |||
471 | int ret; | 659 | int ret; |
472 | 660 | ||
473 | root = debugfs_create_dir(dev_name(dwc->dev), NULL); | 661 | root = debugfs_create_dir(dev_name(dwc->dev), NULL); |
474 | if (IS_ERR(root)) { | 662 | if (!root) { |
475 | ret = PTR_ERR(root); | 663 | ret = -ENOMEM; |
476 | goto err0; | 664 | goto err0; |
477 | } | 665 | } |
478 | 666 | ||
@@ -480,15 +668,29 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc) | |||
480 | 668 | ||
481 | file = debugfs_create_file("regdump", S_IRUGO, root, dwc, | 669 | file = debugfs_create_file("regdump", S_IRUGO, root, dwc, |
482 | &dwc3_regdump_fops); | 670 | &dwc3_regdump_fops); |
483 | if (IS_ERR(file)) { | 671 | if (!file) { |
484 | ret = PTR_ERR(file); | 672 | ret = -ENOMEM; |
485 | goto err1; | 673 | goto err1; |
486 | } | 674 | } |
487 | 675 | ||
488 | file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, | 676 | file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, |
489 | dwc, &dwc3_mode_fops); | 677 | dwc, &dwc3_mode_fops); |
490 | if (IS_ERR(file)) { | 678 | if (!file) { |
491 | ret = PTR_ERR(file); | 679 | ret = -ENOMEM; |
680 | goto err1; | ||
681 | } | ||
682 | |||
683 | file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, | ||
684 | dwc, &dwc3_testmode_fops); | ||
685 | if (!file) { | ||
686 | ret = -ENOMEM; | ||
687 | goto err1; | ||
688 | } | ||
689 | |||
690 | file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, | ||
691 | dwc, &dwc3_link_state_fops); | ||
692 | if (!file) { | ||
693 | ret = -ENOMEM; | ||
492 | goto err1; | 694 | goto err1; |
493 | } | 695 | } |
494 | 696 | ||