aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c117
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.h14
2 files changed, 62 insertions, 69 deletions
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 8bd9ce26bd95..4402d6f042d9 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -24,7 +24,7 @@
24 * 24 *
25 */ 25 */
26 26
27// #define VERBOSE DBG_VERBOSE 27/* #define VERBOSE_DEBUG */
28 28
29#include <linux/device.h> 29#include <linux/device.h>
30#include <linux/module.h> 30#include <linux/module.h>
@@ -38,13 +38,14 @@
38#include <linux/timer.h> 38#include <linux/timer.h>
39#include <linux/list.h> 39#include <linux/list.h>
40#include <linux/interrupt.h> 40#include <linux/interrupt.h>
41#include <linux/proc_fs.h>
42#include <linux/mm.h> 41#include <linux/mm.h>
43#include <linux/platform_device.h> 42#include <linux/platform_device.h>
44#include <linux/dma-mapping.h> 43#include <linux/dma-mapping.h>
45#include <linux/irq.h> 44#include <linux/irq.h>
46#include <linux/clk.h> 45#include <linux/clk.h>
47#include <linux/err.h> 46#include <linux/err.h>
47#include <linux/seq_file.h>
48#include <linux/debugfs.h>
48 49
49#include <asm/byteorder.h> 50#include <asm/byteorder.h>
50#include <asm/dma.h> 51#include <asm/dma.h>
@@ -679,7 +680,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
679 680
680 /* kickstart this i/o queue? */ 681 /* kickstart this i/o queue? */
681 if (list_empty(&ep->queue) && !ep->stopped) { 682 if (list_empty(&ep->queue) && !ep->stopped) {
682 if (ep->desc == 0 /* ep0 */) { 683 if (ep->desc == NULL/* ep0 */) {
683 unsigned length = _req->length; 684 unsigned length = _req->length;
684 685
685 switch (dev->ep0state) { 686 switch (dev->ep0state) {
@@ -733,7 +734,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
733 } 734 }
734 735
735 /* pio or dma irq handler advances the queue. */ 736 /* pio or dma irq handler advances the queue. */
736 if (likely (req != 0)) 737 if (likely(req != NULL))
737 list_add_tail(&req->queue, &ep->queue); 738 list_add_tail(&req->queue, &ep->queue);
738 local_irq_restore(flags); 739 local_irq_restore(flags);
739 740
@@ -993,45 +994,32 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = {
993 994
994/*-------------------------------------------------------------------------*/ 995/*-------------------------------------------------------------------------*/
995 996
996#ifdef CONFIG_USB_GADGET_DEBUG_FILES 997#ifdef CONFIG_USB_GADGET_DEBUG_FS
997
998static const char proc_node_name [] = "driver/udc";
999 998
1000static int 999static int
1001udc_proc_read(char *page, char **start, off_t off, int count, 1000udc_seq_show(struct seq_file *m, void *d)
1002 int *eof, void *_dev)
1003{ 1001{
1004 char *buf = page; 1002 struct pxa2xx_udc *dev = m->private;
1005 struct pxa2xx_udc *dev = _dev;
1006 char *next = buf;
1007 unsigned size = count;
1008 unsigned long flags; 1003 unsigned long flags;
1009 int i, t; 1004 int i;
1010 u32 tmp; 1005 u32 tmp;
1011 1006
1012 if (off != 0)
1013 return 0;
1014
1015 local_irq_save(flags); 1007 local_irq_save(flags);
1016 1008
1017 /* basic device status */ 1009 /* basic device status */
1018 t = scnprintf(next, size, DRIVER_DESC "\n" 1010 seq_printf(m, DRIVER_DESC "\n"
1019 "%s version: %s\nGadget driver: %s\nHost %s\n\n", 1011 "%s version: %s\nGadget driver: %s\nHost %s\n\n",
1020 driver_name, DRIVER_VERSION SIZE_STR "(pio)", 1012 driver_name, DRIVER_VERSION SIZE_STR "(pio)",
1021 dev->driver ? dev->driver->driver.name : "(none)", 1013 dev->driver ? dev->driver->driver.name : "(none)",
1022 is_vbus_present() ? "full speed" : "disconnected"); 1014 is_vbus_present() ? "full speed" : "disconnected");
1023 size -= t;
1024 next += t;
1025 1015
1026 /* registers for device and ep0 */ 1016 /* registers for device and ep0 */
1027 t = scnprintf(next, size, 1017 seq_printf(m,
1028 "uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", 1018 "uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n",
1029 UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); 1019 UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL);
1030 size -= t;
1031 next += t;
1032 1020
1033 tmp = UDCCR; 1021 tmp = UDCCR;
1034 t = scnprintf(next, size, 1022 seq_printf(m,
1035 "udccr %02X =%s%s%s%s%s%s%s%s\n", tmp, 1023 "udccr %02X =%s%s%s%s%s%s%s%s\n", tmp,
1036 (tmp & UDCCR_REM) ? " rem" : "", 1024 (tmp & UDCCR_REM) ? " rem" : "",
1037 (tmp & UDCCR_RSTIR) ? " rstir" : "", 1025 (tmp & UDCCR_RSTIR) ? " rstir" : "",
@@ -1041,11 +1029,9 @@ udc_proc_read(char *page, char **start, off_t off, int count,
1041 (tmp & UDCCR_RSM) ? " rsm" : "", 1029 (tmp & UDCCR_RSM) ? " rsm" : "",
1042 (tmp & UDCCR_UDA) ? " uda" : "", 1030 (tmp & UDCCR_UDA) ? " uda" : "",
1043 (tmp & UDCCR_UDE) ? " ude" : ""); 1031 (tmp & UDCCR_UDE) ? " ude" : "");
1044 size -= t;
1045 next += t;
1046 1032
1047 tmp = UDCCS0; 1033 tmp = UDCCS0;
1048 t = scnprintf(next, size, 1034 seq_printf(m,
1049 "udccs0 %02X =%s%s%s%s%s%s%s%s\n", tmp, 1035 "udccs0 %02X =%s%s%s%s%s%s%s%s\n", tmp,
1050 (tmp & UDCCS0_SA) ? " sa" : "", 1036 (tmp & UDCCS0_SA) ? " sa" : "",
1051 (tmp & UDCCS0_RNE) ? " rne" : "", 1037 (tmp & UDCCS0_RNE) ? " rne" : "",
@@ -1055,28 +1041,22 @@ udc_proc_read(char *page, char **start, off_t off, int count,
1055 (tmp & UDCCS0_FTF) ? " ftf" : "", 1041 (tmp & UDCCS0_FTF) ? " ftf" : "",
1056 (tmp & UDCCS0_IPR) ? " ipr" : "", 1042 (tmp & UDCCS0_IPR) ? " ipr" : "",
1057 (tmp & UDCCS0_OPR) ? " opr" : ""); 1043 (tmp & UDCCS0_OPR) ? " opr" : "");
1058 size -= t;
1059 next += t;
1060 1044
1061 if (dev->has_cfr) { 1045 if (dev->has_cfr) {
1062 tmp = UDCCFR; 1046 tmp = UDCCFR;
1063 t = scnprintf(next, size, 1047 seq_printf(m,
1064 "udccfr %02X =%s%s\n", tmp, 1048 "udccfr %02X =%s%s\n", tmp,
1065 (tmp & UDCCFR_AREN) ? " aren" : "", 1049 (tmp & UDCCFR_AREN) ? " aren" : "",
1066 (tmp & UDCCFR_ACM) ? " acm" : ""); 1050 (tmp & UDCCFR_ACM) ? " acm" : "");
1067 size -= t;
1068 next += t;
1069 } 1051 }
1070 1052
1071 if (!is_vbus_present() || !dev->driver) 1053 if (!is_vbus_present() || !dev->driver)
1072 goto done; 1054 goto done;
1073 1055
1074 t = scnprintf(next, size, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", 1056 seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",
1075 dev->stats.write.bytes, dev->stats.write.ops, 1057 dev->stats.write.bytes, dev->stats.write.ops,
1076 dev->stats.read.bytes, dev->stats.read.ops, 1058 dev->stats.read.bytes, dev->stats.read.ops,
1077 dev->stats.irqs); 1059 dev->stats.irqs);
1078 size -= t;
1079 next += t;
1080 1060
1081 /* dump endpoint queues */ 1061 /* dump endpoint queues */
1082 for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { 1062 for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) {
@@ -1084,61 +1064,68 @@ udc_proc_read(char *page, char **start, off_t off, int count,
1084 struct pxa2xx_request *req; 1064 struct pxa2xx_request *req;
1085 1065
1086 if (i != 0) { 1066 if (i != 0) {
1087 const struct usb_endpoint_descriptor *d; 1067 const struct usb_endpoint_descriptor *desc;
1088 1068
1089 d = ep->desc; 1069 desc = ep->desc;
1090 if (!d) 1070 if (!desc)
1091 continue; 1071 continue;
1092 tmp = *dev->ep [i].reg_udccs; 1072 tmp = *dev->ep [i].reg_udccs;
1093 t = scnprintf(next, size, 1073 seq_printf(m,
1094 "%s max %d %s udccs %02x irqs %lu\n", 1074 "%s max %d %s udccs %02x irqs %lu\n",
1095 ep->ep.name, le16_to_cpu (d->wMaxPacketSize), 1075 ep->ep.name, le16_to_cpu(desc->wMaxPacketSize),
1096 "pio", tmp, ep->pio_irqs); 1076 "pio", tmp, ep->pio_irqs);
1097 /* TODO translate all five groups of udccs bits! */ 1077 /* TODO translate all five groups of udccs bits! */
1098 1078
1099 } else /* ep0 should only have one transfer queued */ 1079 } else /* ep0 should only have one transfer queued */
1100 t = scnprintf(next, size, "ep0 max 16 pio irqs %lu\n", 1080 seq_printf(m, "ep0 max 16 pio irqs %lu\n",
1101 ep->pio_irqs); 1081 ep->pio_irqs);
1102 if (t <= 0 || t > size)
1103 goto done;
1104 size -= t;
1105 next += t;
1106 1082
1107 if (list_empty(&ep->queue)) { 1083 if (list_empty(&ep->queue)) {
1108 t = scnprintf(next, size, "\t(nothing queued)\n"); 1084 seq_printf(m, "\t(nothing queued)\n");
1109 if (t <= 0 || t > size)
1110 goto done;
1111 size -= t;
1112 next += t;
1113 continue; 1085 continue;
1114 } 1086 }
1115 list_for_each_entry(req, &ep->queue, queue) { 1087 list_for_each_entry(req, &ep->queue, queue) {
1116 t = scnprintf(next, size, 1088 seq_printf(m,
1117 "\treq %p len %d/%d buf %p\n", 1089 "\treq %p len %d/%d buf %p\n",
1118 &req->req, req->req.actual, 1090 &req->req, req->req.actual,
1119 req->req.length, req->req.buf); 1091 req->req.length, req->req.buf);
1120 if (t <= 0 || t > size)
1121 goto done;
1122 size -= t;
1123 next += t;
1124 } 1092 }
1125 } 1093 }
1126 1094
1127done: 1095done:
1128 local_irq_restore(flags); 1096 local_irq_restore(flags);
1129 *eof = 1; 1097 return 0;
1130 return count - size;
1131} 1098}
1132 1099
1133#define create_proc_files() \ 1100static int
1134 create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev) 1101udc_debugfs_open(struct inode *inode, struct file *file)
1135#define remove_proc_files() \ 1102{
1136 remove_proc_entry(proc_node_name, NULL) 1103 return single_open(file, udc_seq_show, inode->i_private);
1104}
1105
1106static const struct file_operations debug_fops = {
1107 .open = udc_debugfs_open,
1108 .read = seq_read,
1109 .llseek = seq_lseek,
1110 .release = single_release,
1111 .owner = THIS_MODULE,
1112};
1113
1114#define create_debug_files(dev) \
1115 do { \
1116 dev->debugfs_udc = debugfs_create_file(dev->gadget.name, \
1117 S_IRUGO, NULL, dev, &debug_fops); \
1118 } while (0)
1119#define remove_debug_files(dev) \
1120 do { \
1121 if (dev->debugfs_udc) \
1122 debugfs_remove(dev->debugfs_udc); \
1123 } while (0)
1137 1124
1138#else /* !CONFIG_USB_GADGET_DEBUG_FILES */ 1125#else /* !CONFIG_USB_GADGET_DEBUG_FILES */
1139 1126
1140#define create_proc_files() do {} while (0) 1127#define create_debug_files(dev) do {} while (0)
1141#define remove_proc_files() do {} while (0) 1128#define remove_debug_files(dev) do {} while (0)
1142 1129
1143#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ 1130#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
1144 1131
@@ -2246,7 +2233,7 @@ lubbock_fail0:
2246 goto err_vbus_irq; 2233 goto err_vbus_irq;
2247 } 2234 }
2248 } 2235 }
2249 create_proc_files(); 2236 create_debug_files(dev);
2250 2237
2251 return 0; 2238 return 0;
2252 2239
@@ -2283,7 +2270,7 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
2283 return -EBUSY; 2270 return -EBUSY;
2284 2271
2285 udc_disable(dev); 2272 udc_disable(dev);
2286 remove_proc_files(); 2273 remove_debug_files(dev);
2287 2274
2288 if (dev->got_irq) { 2275 if (dev->got_irq) {
2289 free_irq(platform_get_irq(pdev, 0), dev); 2276 free_irq(platform_get_irq(pdev, 0), dev);
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
index 97a8c45ccd81..b67e3ff5e4eb 100644
--- a/drivers/usb/gadget/pxa2xx_udc.h
+++ b/drivers/usb/gadget/pxa2xx_udc.h
@@ -129,6 +129,10 @@ struct pxa2xx_udc {
129 struct pxa2xx_udc_mach_info *mach; 129 struct pxa2xx_udc_mach_info *mach;
130 u64 dma_mask; 130 u64 dma_mask;
131 struct pxa2xx_ep ep [PXA_UDC_NUM_ENDPOINTS]; 131 struct pxa2xx_ep ep [PXA_UDC_NUM_ENDPOINTS];
132
133#ifdef CONFIG_USB_GADGET_DEBUG_FS
134 struct dentry *debugfs_udc;
135#endif
132}; 136};
133 137
134/*-------------------------------------------------------------------------*/ 138/*-------------------------------------------------------------------------*/
@@ -155,13 +159,15 @@ static struct pxa2xx_udc *the_controller;
155 159
156#ifdef DEBUG 160#ifdef DEBUG
157 161
162static int is_vbus_present(void);
163
158static const char *state_name[] = { 164static const char *state_name[] = {
159 "EP0_IDLE", 165 "EP0_IDLE",
160 "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE", 166 "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE",
161 "EP0_END_XFER", "EP0_STALL" 167 "EP0_END_XFER", "EP0_STALL"
162}; 168};
163 169
164#ifdef VERBOSE 170#ifdef VERBOSE_DEBUG
165# define UDC_DEBUG DBG_VERBOSE 171# define UDC_DEBUG DBG_VERBOSE
166#else 172#else
167# define UDC_DEBUG DBG_NORMAL 173# define UDC_DEBUG DBG_NORMAL
@@ -207,7 +213,7 @@ dump_state(struct pxa2xx_udc *dev)
207 unsigned i; 213 unsigned i;
208 214
209 DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n", 215 DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n",
210 is_usb_connected() ? "host " : "disconnected", 216 is_vbus_present() ? "host " : "disconnected",
211 state_name[dev->ep0state], 217 state_name[dev->ep0state],
212 UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL); 218 UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL);
213 dump_udccr("udccr"); 219 dump_udccr("udccr");
@@ -224,7 +230,7 @@ dump_state(struct pxa2xx_udc *dev)
224 } else 230 } else
225 DMSG("ep0 driver '%s'\n", dev->driver->driver.name); 231 DMSG("ep0 driver '%s'\n", dev->driver->driver.name);
226 232
227 if (!is_usb_connected()) 233 if (!is_vbus_present())
228 return; 234 return;
229 235
230 dump_udccs0 ("udccs0"); 236 dump_udccs0 ("udccs0");
@@ -233,7 +239,7 @@ dump_state(struct pxa2xx_udc *dev)
233 dev->stats.read.bytes, dev->stats.read.ops); 239 dev->stats.read.bytes, dev->stats.read.ops);
234 240
235 for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) { 241 for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) {
236 if (dev->ep [i].desc == 0) 242 if (dev->ep [i].desc == NULL)
237 continue; 243 continue;
238 DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs); 244 DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs);
239 } 245 }