diff options
Diffstat (limited to 'drivers/usb/dwc3/debugfs.c')
-rw-r--r-- | drivers/usb/dwc3/debugfs.c | 83 |
1 files changed, 80 insertions, 3 deletions
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index da1ad77d8d51..87d403df1f3f 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c | |||
@@ -44,12 +44,12 @@ | |||
44 | #include <linux/debugfs.h> | 44 | #include <linux/debugfs.h> |
45 | #include <linux/seq_file.h> | 45 | #include <linux/seq_file.h> |
46 | #include <linux/delay.h> | 46 | #include <linux/delay.h> |
47 | 47 | #include <linux/uaccess.h> | |
48 | #include <asm/uaccess.h> | ||
49 | 48 | ||
50 | #include "core.h" | 49 | #include "core.h" |
51 | #include "gadget.h" | 50 | #include "gadget.h" |
52 | #include "io.h" | 51 | #include "io.h" |
52 | #include "debug.h" | ||
53 | 53 | ||
54 | struct dwc3_register { | 54 | struct dwc3_register { |
55 | const char *name; | 55 | const char *name; |
@@ -405,6 +405,75 @@ static const struct file_operations dwc3_regdump_fops = { | |||
405 | .release = single_release, | 405 | .release = single_release, |
406 | }; | 406 | }; |
407 | 407 | ||
408 | static int dwc3_mode_show(struct seq_file *s, void *unused) | ||
409 | { | ||
410 | struct dwc3 *dwc = s->private; | ||
411 | unsigned long flags; | ||
412 | u32 reg; | ||
413 | |||
414 | spin_lock_irqsave(&dwc->lock, flags); | ||
415 | reg = dwc3_readl(dwc->regs, DWC3_GCTL); | ||
416 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
417 | |||
418 | switch (DWC3_GCTL_PRTCAP(reg)) { | ||
419 | case DWC3_GCTL_PRTCAP_HOST: | ||
420 | seq_printf(s, "host\n"); | ||
421 | break; | ||
422 | case DWC3_GCTL_PRTCAP_DEVICE: | ||
423 | seq_printf(s, "device\n"); | ||
424 | break; | ||
425 | case DWC3_GCTL_PRTCAP_OTG: | ||
426 | seq_printf(s, "OTG\n"); | ||
427 | break; | ||
428 | default: | ||
429 | seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg)); | ||
430 | } | ||
431 | |||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | static int dwc3_mode_open(struct inode *inode, struct file *file) | ||
436 | { | ||
437 | return single_open(file, dwc3_mode_show, inode->i_private); | ||
438 | } | ||
439 | |||
440 | static ssize_t dwc3_mode_write(struct file *file, | ||
441 | const char __user *ubuf, size_t count, loff_t *ppos) | ||
442 | { | ||
443 | struct seq_file *s = file->private_data; | ||
444 | struct dwc3 *dwc = s->private; | ||
445 | unsigned long flags; | ||
446 | u32 mode = 0; | ||
447 | char buf[32]; | ||
448 | |||
449 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
450 | return -EFAULT; | ||
451 | |||
452 | if (!strncmp(buf, "host", 4)) | ||
453 | mode |= DWC3_GCTL_PRTCAP_HOST; | ||
454 | |||
455 | if (!strncmp(buf, "device", 6)) | ||
456 | mode |= DWC3_GCTL_PRTCAP_DEVICE; | ||
457 | |||
458 | if (!strncmp(buf, "otg", 3)) | ||
459 | mode |= DWC3_GCTL_PRTCAP_OTG; | ||
460 | |||
461 | if (mode) { | ||
462 | spin_lock_irqsave(&dwc->lock, flags); | ||
463 | dwc3_set_mode(dwc, mode); | ||
464 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
465 | } | ||
466 | return count; | ||
467 | } | ||
468 | |||
469 | static const struct file_operations dwc3_mode_fops = { | ||
470 | .open = dwc3_mode_open, | ||
471 | .write = dwc3_mode_write, | ||
472 | .read = seq_read, | ||
473 | .llseek = seq_lseek, | ||
474 | .release = single_release, | ||
475 | }; | ||
476 | |||
408 | int __devinit dwc3_debugfs_init(struct dwc3 *dwc) | 477 | int __devinit dwc3_debugfs_init(struct dwc3 *dwc) |
409 | { | 478 | { |
410 | struct dentry *root; | 479 | struct dentry *root; |
@@ -412,7 +481,7 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc) | |||
412 | int ret; | 481 | int ret; |
413 | 482 | ||
414 | root = debugfs_create_dir(dev_name(dwc->dev), NULL); | 483 | root = debugfs_create_dir(dev_name(dwc->dev), NULL); |
415 | if (IS_ERR(root)){ | 484 | if (IS_ERR(root)) { |
416 | ret = PTR_ERR(root); | 485 | ret = PTR_ERR(root); |
417 | goto err0; | 486 | goto err0; |
418 | } | 487 | } |
@@ -425,6 +494,14 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc) | |||
425 | ret = PTR_ERR(file); | 494 | ret = PTR_ERR(file); |
426 | goto err1; | 495 | goto err1; |
427 | } | 496 | } |
497 | |||
498 | file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, | ||
499 | dwc, &dwc3_mode_fops); | ||
500 | if (IS_ERR(file)) { | ||
501 | ret = PTR_ERR(file); | ||
502 | goto err1; | ||
503 | } | ||
504 | |||
428 | return 0; | 505 | return 0; |
429 | 506 | ||
430 | err1: | 507 | err1: |