diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-20 19:26:30 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-20 19:26:30 +0100 |
commit | ed378a52dabf77b406b447fd3238f83ea24b71fa (patch) | |
tree | 07e1a7ec2d1c08767ee81b9910f5912b80502632 /drivers/usb/dwc3/debugfs.c | |
parent | Merge tag 'tty-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty (diff) | |
parent | net: qmi_wwan: add support for ZTE MF820D (diff) | |
download | linux-ed378a52dabf77b406b447fd3238f83ea24b71fa.tar.xz linux-ed378a52dabf77b406b447fd3238f83ea24b71fa.zip |
Merge tag 'usb-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB merge for 3.4-rc1 from Greg KH:
"Here's the big USB merge for the 3.4-rc1 merge window.
Lots of gadget driver reworks here, driver updates, xhci changes, some
new drivers added, usb-serial core reworking to fix some bugs, and
other various minor things.
There are some patches touching arch code, but they have all been
acked by the various arch maintainers."
* tag 'usb-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (302 commits)
net: qmi_wwan: add support for ZTE MF820D
USB: option: add ZTE MF820D
usb: gadget: f_fs: Remove lock is held before freeing checks
USB: option: make interface blacklist work again
usb/ub: deprecate & schedule for removal the "Low Performance USB Block" driver
USB: ohci-pxa27x: add clk_prepare/clk_unprepare calls
USB: use generic platform driver on ath79
USB: EHCI: Add a generic platform device driver
USB: OHCI: Add a generic platform device driver
USB: ftdi_sio: new PID: LUMEL PD12
USB: ftdi_sio: add support for FT-X series devices
USB: serial: mos7840: Fixed MCS7820 device attach problem
usb: Don't make USB_ARCH_HAS_{XHCI,OHCI,EHCI} depend on USB_SUPPORT.
usb gadget: fix a section mismatch when compiling g_ffs with CONFIG_USB_FUNCTIONFS_ETH
USB: ohci-nxp: Remove i2c_write(), use smbus
USB: ohci-nxp: Support for LPC32xx
USB: ohci-nxp: Rename symbols from pnx4008 to nxp
USB: OHCI-HCD: Rename ohci-pnx4008 to ohci-nxp
usb: gadget: Kconfig: fix typo for 'different'
usb: dwc3: pci: fix another failure path in dwc3_pci_probe()
...
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 @@ #include <linux/delay.h> #include <linux/uaccess.h> +#include <linux/usb/ch9.h> + #include "core.h" #include "gadget.h" #include "io.h" @@ -464,6 +466,192 @@ static const struct file_operations dwc3_mode_fops = { .release = single_release, }; +static int dwc3_testmode_show(struct seq_file *s, void *unused) +{ + struct dwc3 *dwc = s->private; + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&dwc->lock, flags); + reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg &= DWC3_DCTL_TSTCTRL_MASK; + reg >>= 1; + spin_unlock_irqrestore(&dwc->lock, flags); + + switch (reg) { + case 0: + seq_printf(s, "no test\n"); + break; + case TEST_J: + seq_printf(s, "test_j\n"); + break; + case TEST_K: + seq_printf(s, "test_k\n"); + break; + case TEST_SE0_NAK: + seq_printf(s, "test_se0_nak\n"); + break; + case TEST_PACKET: + seq_printf(s, "test_packet\n"); + break; + case TEST_FORCE_EN: + seq_printf(s, "test_force_enable\n"); + break; + default: + seq_printf(s, "UNKNOWN %d\n", reg); + } + + return 0; +} + +static int dwc3_testmode_open(struct inode *inode, struct file *file) +{ + return single_open(file, dwc3_testmode_show, inode->i_private); +} + +static ssize_t dwc3_testmode_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct dwc3 *dwc = s->private; + unsigned long flags; + u32 testmode = 0; + char buf[32]; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (!strncmp(buf, "test_j", 6)) + testmode = TEST_J; + else if (!strncmp(buf, "test_k", 6)) + testmode = TEST_K; + else if (!strncmp(buf, "test_se0_nak", 12)) + testmode = TEST_SE0_NAK; + else if (!strncmp(buf, "test_packet", 11)) + testmode = TEST_PACKET; + else if (!strncmp(buf, "test_force_enable", 17)) + testmode = TEST_FORCE_EN; + else + testmode = 0; + + spin_lock_irqsave(&dwc->lock, flags); + dwc3_gadget_set_test_mode(dwc, testmode); + spin_unlock_irqrestore(&dwc->lock, flags); + + return count; +} + +static const struct file_operations dwc3_testmode_fops = { + .open = dwc3_testmode_open, + .write = dwc3_testmode_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int dwc3_link_state_show(struct seq_file *s, void *unused) +{ + struct dwc3 *dwc = s->private; + unsigned long flags; + enum dwc3_link_state state; + u32 reg; + + spin_lock_irqsave(&dwc->lock, flags); + reg = dwc3_readl(dwc->regs, DWC3_DSTS); + state = DWC3_DSTS_USBLNKST(reg); + spin_unlock_irqrestore(&dwc->lock, flags); + + switch (state) { + case DWC3_LINK_STATE_U0: + seq_printf(s, "U0\n"); + break; + case DWC3_LINK_STATE_U1: + seq_printf(s, "U1\n"); + break; + case DWC3_LINK_STATE_U2: + seq_printf(s, "U2\n"); + break; + case DWC3_LINK_STATE_U3: + seq_printf(s, "U3\n"); + break; + case DWC3_LINK_STATE_SS_DIS: + seq_printf(s, "SS.Disabled\n"); + break; + case DWC3_LINK_STATE_RX_DET: + seq_printf(s, "Rx.Detect\n"); + break; + case DWC3_LINK_STATE_SS_INACT: + seq_printf(s, "SS.Inactive\n"); + break; + case DWC3_LINK_STATE_POLL: + seq_printf(s, "Poll\n"); + break; + case DWC3_LINK_STATE_RECOV: + seq_printf(s, "Recovery\n"); + break; + case DWC3_LINK_STATE_HRESET: + seq_printf(s, "HRESET\n"); + break; + case DWC3_LINK_STATE_CMPLY: + seq_printf(s, "Compliance\n"); + break; + case DWC3_LINK_STATE_LPBK: + seq_printf(s, "Loopback\n"); + break; + default: + seq_printf(s, "UNKNOWN %d\n", reg); + } + + return 0; +} + +static int dwc3_link_state_open(struct inode *inode, struct file *file) +{ + return single_open(file, dwc3_link_state_show, inode->i_private); +} + +static ssize_t dwc3_link_state_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct dwc3 *dwc = s->private; + unsigned long flags; + enum dwc3_link_state state = 0; + char buf[32]; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (!strncmp(buf, "SS.Disabled", 11)) + state = DWC3_LINK_STATE_SS_DIS; + else if (!strncmp(buf, "Rx.Detect", 9)) + state = DWC3_LINK_STATE_RX_DET; + else if (!strncmp(buf, "SS.Inactive", 11)) + state = DWC3_LINK_STATE_SS_INACT; + else if (!strncmp(buf, "Recovery", 8)) + state = DWC3_LINK_STATE_RECOV; + else if (!strncmp(buf, "Compliance", 10)) + state = DWC3_LINK_STATE_CMPLY; + else if (!strncmp(buf, "Loopback", 8)) + state = DWC3_LINK_STATE_LPBK; + else + return -EINVAL; + + spin_lock_irqsave(&dwc->lock, flags); + dwc3_gadget_set_link_state(dwc, state); + spin_unlock_irqrestore(&dwc->lock, flags); + + return count; +} + +static const struct file_operations dwc3_link_state_fops = { + .open = dwc3_link_state_open, + .write = dwc3_link_state_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + int __devinit dwc3_debugfs_init(struct dwc3 *dwc) { struct dentry *root; @@ -471,8 +659,8 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc) int ret; root = debugfs_create_dir(dev_name(dwc->dev), NULL); - if (IS_ERR(root)) { - ret = PTR_ERR(root); + if (!root) { + ret = -ENOMEM; goto err0; } @@ -480,15 +668,29 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc) file = debugfs_create_file("regdump", S_IRUGO, root, dwc, &dwc3_regdump_fops); - if (IS_ERR(file)) { - ret = PTR_ERR(file); + if (!file) { + ret = -ENOMEM; goto err1; } file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, dwc, &dwc3_mode_fops); - if (IS_ERR(file)) { - ret = PTR_ERR(file); + if (!file) { + ret = -ENOMEM; + goto err1; + } + + file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, + dwc, &dwc3_testmode_fops); + if (!file) { + ret = -ENOMEM; + goto err1; + } + + file = debugfs_create_file("link_state", S_IRUGO | S_IWUSR, root, + dwc, &dwc3_link_state_fops); + if (!file) { + ret = -ENOMEM; goto err1; } |