From a016c578059cd96bc455948c7068a68fded4ca32 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 17 Oct 2011 08:50:39 +0300 Subject: [PATCH] --- yaml --- r: 280814 b: refs/heads/master c: 0b9fe32deece53c9bc6d1e6d17a85ef1eb2e294b h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/usb/dwc3/core.h | 1 + trunk/drivers/usb/dwc3/debugfs.c | 82 ++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 10e4a740ebba..a287f65d9572 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f96a6ec1db1ac730b5a031f2c2f7fcc6b07459d8 +refs/heads/master: 0b9fe32deece53c9bc6d1e6d17a85ef1eb2e294b diff --git a/trunk/drivers/usb/dwc3/core.h b/trunk/drivers/usb/dwc3/core.h index 513a7391099f..6f1e8c98d78d 100644 --- a/trunk/drivers/usb/dwc3/core.h +++ b/trunk/drivers/usb/dwc3/core.h @@ -154,6 +154,7 @@ #define DWC3_GCTL_CLK_PIPEHALF (2) #define DWC3_GCTL_CLK_MASK (3) +#define DWC3_GCTL_PRTCAP(n) (((n) & (3 << 12)) >> 12) #define DWC3_GCTL_PRTCAPDIR(n) (n << 12) #define DWC3_GCTL_PRTCAP_HOST 1 #define DWC3_GCTL_PRTCAP_DEVICE 2 diff --git a/trunk/drivers/usb/dwc3/debugfs.c b/trunk/drivers/usb/dwc3/debugfs.c index da1ad77d8d51..fc49334a01cf 100644 --- a/trunk/drivers/usb/dwc3/debugfs.c +++ b/trunk/drivers/usb/dwc3/debugfs.c @@ -405,6 +405,80 @@ 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 reg; + char buf[32]; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + spin_lock_irqsave(&dwc->lock, flags); + reg = dwc3_readl(dwc->regs, DWC3_GCTL); + spin_unlock_irqrestore(&dwc->lock, flags); + + reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)); + + if (!strncmp(buf, "host", 4)) + reg |= DWC3_GCTL_PRTCAP(DWC3_GCTL_PRTCAP_HOST); + + if (!strncmp(buf, "device", 6)) + reg |= DWC3_GCTL_PRTCAP(DWC3_GCTL_PRTCAP_DEVICE); + + if (!strncmp(buf, "otg", 3)) + reg |= DWC3_GCTL_PRTCAP(DWC3_GCTL_PRTCAP_OTG); + + spin_lock_irqsave(&dwc->lock, flags); + dwc3_writel(dwc->regs, DWC3_GCTL, reg); + 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; @@ -425,6 +499,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: