diff options
-rw-r--r-- | drivers/usb/gadget/pxa2xx_udc.c | 117 | ||||
-rw-r--r-- | drivers/usb/gadget/pxa2xx_udc.h | 14 |
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 | |||
998 | static const char proc_node_name [] = "driver/udc"; | ||
999 | 998 | ||
1000 | static int | 999 | static int |
1001 | udc_proc_read(char *page, char **start, off_t off, int count, | 1000 | udc_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 | ||
1127 | done: | 1095 | done: |
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() \ | 1100 | static int |
1134 | create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev) | 1101 | udc_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 | |||
1106 | static 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 | ||
162 | static int is_vbus_present(void); | ||
163 | |||
158 | static const char *state_name[] = { | 164 | static 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 | } |