]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/usb/dwc3/debugfs.c
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
[linux-2.6.git] / drivers / usb / dwc3 / debugfs.c
index fcfa91517ea1b696523583110f8a20470fc16dc2..433c97c15fc5447f6cbfb4c5b974ae3fbe674ff2 100644 (file)
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/delay.h>
-
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 #include "core.h"
 #include "gadget.h"
 #include "io.h"
+#include "debug.h"
 
 #define dump_register(nm)                              \
 {                                                      \
@@ -395,6 +395,75 @@ static const struct file_operations dwc3_regdump_fops = {
        .release                = single_release,
 };
 
+static int dwc3_mode_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_GCTL);
+       spin_unlock_irqrestore(&dwc->lock, flags);
+
+       switch (DWC3_GCTL_PRTCAP(reg)) {
+       case DWC3_GCTL_PRTCAP_HOST:
+               seq_printf(s, "host\n");
+               break;
+       case DWC3_GCTL_PRTCAP_DEVICE:
+               seq_printf(s, "device\n");
+               break;
+       case DWC3_GCTL_PRTCAP_OTG:
+               seq_printf(s, "OTG\n");
+               break;
+       default:
+               seq_printf(s, "UNKNOWN %08x\n", DWC3_GCTL_PRTCAP(reg));
+       }
+
+       return 0;
+}
+
+static int dwc3_mode_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dwc3_mode_show, inode->i_private);
+}
+
+static ssize_t dwc3_mode_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                     mode = 0;
+       char                    buf[32];
+
+       if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+               return -EFAULT;
+
+       if (!strncmp(buf, "host", 4))
+               mode |= DWC3_GCTL_PRTCAP_HOST;
+
+       if (!strncmp(buf, "device", 6))
+               mode |= DWC3_GCTL_PRTCAP_DEVICE;
+
+       if (!strncmp(buf, "otg", 3))
+               mode |= DWC3_GCTL_PRTCAP_OTG;
+
+       if (mode) {
+               spin_lock_irqsave(&dwc->lock, flags);
+               dwc3_set_mode(dwc, mode);
+               spin_unlock_irqrestore(&dwc->lock, flags);
+       }
+       return count;
+}
+
+static const struct file_operations dwc3_mode_fops = {
+       .open                   = dwc3_mode_open,
+       .write                  = dwc3_mode_write,
+       .read                   = seq_read,
+       .llseek                 = seq_lseek,
+       .release                = single_release,
+};
+
 int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
 {
        struct dentry           *root;
@@ -402,7 +471,7 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
        int                     ret;
 
        root = debugfs_create_dir(dev_name(dwc->dev), NULL);
-       if (IS_ERR(root)){
+       if (IS_ERR(root)) {
                ret = PTR_ERR(root);
                goto err0;
        }
@@ -415,6 +484,14 @@ int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
                ret = PTR_ERR(file);
                goto err1;
        }
+
+       file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root,
+                       dwc, &dwc3_mode_fops);
+       if (IS_ERR(file)) {
+               ret = PTR_ERR(file);
+               goto err1;
+       }
+
        return 0;
 
 err1: