diff options
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/Kconfig | 9 | ||||
-rw-r--r-- | drivers/usb/gadget/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/acm_ms.c | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/at91_udc.c | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/composite.c | 7 | ||||
-rw-r--r-- | drivers/usb/gadget/f_fs.c | 7 | ||||
-rw-r--r-- | drivers/usb/gadget/f_hid.c | 208 | ||||
-rw-r--r-- | drivers/usb/gadget/f_mass_storage.c | 133 | ||||
-rw-r--r-- | drivers/usb/gadget/f_uvc.c | 287 | ||||
-rw-r--r-- | drivers/usb/gadget/f_uvc.h | 8 | ||||
-rw-r--r-- | drivers/usb/gadget/fsl_mxc_udc.c | 74 | ||||
-rw-r--r-- | drivers/usb/gadget/fsl_udc_core.c | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/imx_udc.c | 6 | ||||
-rw-r--r-- | drivers/usb/gadget/lpc32xx_udc.c | 85 | ||||
-rw-r--r-- | drivers/usb/gadget/mv_u3d.h | 320 | ||||
-rw-r--r-- | drivers/usb/gadget/mv_u3d_core.c | 2098 | ||||
-rw-r--r-- | drivers/usb/gadget/omap_udc.c | 403 | ||||
-rw-r--r-- | drivers/usb/gadget/pch_udc.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/s3c-hsotg.c | 215 | ||||
-rw-r--r-- | drivers/usb/gadget/storage_common.c | 63 | ||||
-rw-r--r-- | drivers/usb/gadget/u_ether.c | 12 | ||||
-rw-r--r-- | drivers/usb/gadget/uvc.h | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/webcam.c | 29 |
23 files changed, 3283 insertions, 691 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bddc8fd9a7be..5e242c34088d 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -321,6 +321,15 @@ config USB_MV_UDC | |||
321 | USB2.0 OTG controller, which can be configured as high speed or | 321 | USB2.0 OTG controller, which can be configured as high speed or |
322 | full speed USB peripheral. | 322 | full speed USB peripheral. |
323 | 323 | ||
324 | config USB_MV_U3D | ||
325 | tristate "MARVELL PXA2128 USB 3.0 controller" | ||
326 | depends on CPU_MMP3 | ||
327 | select USB_GADGET_DUALSPEED | ||
328 | select USB_GADGET_SUPERSPEED | ||
329 | help | ||
330 | MARVELL PXA2128 Processor series include a super speed USB3.0 device | ||
331 | controller, which support super speed USB peripheral. | ||
332 | |||
324 | # | 333 | # |
325 | # Controllers available in both integrated and discrete versions | 334 | # Controllers available in both integrated and discrete versions |
326 | # | 335 | # |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 1811513f1c27..3fd8cd09d2c1 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -29,6 +29,7 @@ obj-$(CONFIG_USB_EG20T) += pch_udc.o | |||
29 | obj-$(CONFIG_USB_MV_UDC) += mv_udc.o | 29 | obj-$(CONFIG_USB_MV_UDC) += mv_udc.o |
30 | mv_udc-y := mv_udc_core.o | 30 | mv_udc-y := mv_udc_core.o |
31 | obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o | 31 | obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o |
32 | obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o | ||
32 | 33 | ||
33 | # | 34 | # |
34 | # USB gadget drivers | 35 | # USB gadget drivers |
diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index fdb7aec3bd0c..75b8a691fd00 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c | |||
@@ -235,6 +235,7 @@ static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) | |||
235 | static struct usb_composite_driver acm_ms_driver = { | 235 | static struct usb_composite_driver acm_ms_driver = { |
236 | .name = "g_acm_ms", | 236 | .name = "g_acm_ms", |
237 | .dev = &device_desc, | 237 | .dev = &device_desc, |
238 | .max_speed = USB_SPEED_SUPER, | ||
238 | .strings = dev_strings, | 239 | .strings = dev_strings, |
239 | .unbind = __exit_p(acm_ms_unbind), | 240 | .unbind = __exit_p(acm_ms_unbind), |
240 | }; | 241 | }; |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 1a4430f315c3..c9e66dfb02e6 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -1634,6 +1634,7 @@ static int at91_start(struct usb_gadget *gadget, | |||
1634 | udc = container_of(gadget, struct at91_udc, gadget); | 1634 | udc = container_of(gadget, struct at91_udc, gadget); |
1635 | udc->driver = driver; | 1635 | udc->driver = driver; |
1636 | udc->gadget.dev.driver = &driver->driver; | 1636 | udc->gadget.dev.driver = &driver->driver; |
1637 | udc->gadget.dev.of_node = udc->pdev->dev.of_node; | ||
1637 | dev_set_drvdata(&udc->gadget.dev, &driver->driver); | 1638 | dev_set_drvdata(&udc->gadget.dev, &driver->driver); |
1638 | udc->enabled = 1; | 1639 | udc->enabled = 1; |
1639 | udc->selfpowered = 1; | 1640 | udc->selfpowered = 1; |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 390749bbb0c3..3f72110da1b0 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -117,6 +117,7 @@ int config_ep_by_speed(struct usb_gadget *g, | |||
117 | struct usb_function *f, | 117 | struct usb_function *f, |
118 | struct usb_ep *_ep) | 118 | struct usb_ep *_ep) |
119 | { | 119 | { |
120 | struct usb_composite_dev *cdev = get_gadget_data(g); | ||
120 | struct usb_endpoint_descriptor *chosen_desc = NULL; | 121 | struct usb_endpoint_descriptor *chosen_desc = NULL; |
121 | struct usb_descriptor_header **speed_desc = NULL; | 122 | struct usb_descriptor_header **speed_desc = NULL; |
122 | 123 | ||
@@ -180,10 +181,12 @@ ep_found: | |||
180 | _ep->mult = comp_desc->bmAttributes & 0x3; | 181 | _ep->mult = comp_desc->bmAttributes & 0x3; |
181 | case USB_ENDPOINT_XFER_BULK: | 182 | case USB_ENDPOINT_XFER_BULK: |
182 | case USB_ENDPOINT_XFER_INT: | 183 | case USB_ENDPOINT_XFER_INT: |
183 | _ep->maxburst = comp_desc->bMaxBurst; | 184 | _ep->maxburst = comp_desc->bMaxBurst + 1; |
184 | break; | 185 | break; |
185 | default: | 186 | default: |
186 | /* Do nothing for control endpoints */ | 187 | if (comp_desc->bMaxBurst != 0) |
188 | ERROR(cdev, "ep0 bMaxBurst must be 0\n"); | ||
189 | _ep->maxburst = 1; | ||
187 | break; | 190 | break; |
188 | } | 191 | } |
189 | } | 192 | } |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index dcd1c7fbb016..8adc79d1b402 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
22 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
23 | #include <linux/export.h> | 23 | #include <linux/export.h> |
24 | #include <linux/hid.h> | ||
24 | #include <asm/unaligned.h> | 25 | #include <asm/unaligned.h> |
25 | 26 | ||
26 | #include <linux/usb/composite.h> | 27 | #include <linux/usb/composite.h> |
@@ -1671,6 +1672,12 @@ static int __must_check ffs_do_desc(char *data, unsigned len, | |||
1671 | } | 1672 | } |
1672 | break; | 1673 | break; |
1673 | 1674 | ||
1675 | case HID_DT_HID: | ||
1676 | pr_vdebug("hid descriptor\n"); | ||
1677 | if (length != sizeof(struct hid_descriptor)) | ||
1678 | goto inv_length; | ||
1679 | break; | ||
1680 | |||
1674 | case USB_DT_OTG: | 1681 | case USB_DT_OTG: |
1675 | if (length != sizeof(struct usb_otg_descriptor)) | 1682 | if (length != sizeof(struct usb_otg_descriptor)) |
1676 | goto inv_length; | 1683 | goto inv_length; |
diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c index 3b3932c55361..16a8b1c15c62 100644 --- a/drivers/usb/gadget/f_hid.c +++ b/drivers/usb/gadget/f_hid.c | |||
@@ -26,6 +26,12 @@ static struct class *hidg_class; | |||
26 | /*-------------------------------------------------------------------------*/ | 26 | /*-------------------------------------------------------------------------*/ |
27 | /* HID gadget struct */ | 27 | /* HID gadget struct */ |
28 | 28 | ||
29 | struct f_hidg_req_list { | ||
30 | struct usb_request *req; | ||
31 | unsigned int pos; | ||
32 | struct list_head list; | ||
33 | }; | ||
34 | |||
29 | struct f_hidg { | 35 | struct f_hidg { |
30 | /* configuration */ | 36 | /* configuration */ |
31 | unsigned char bInterfaceSubClass; | 37 | unsigned char bInterfaceSubClass; |
@@ -35,10 +41,10 @@ struct f_hidg { | |||
35 | unsigned short report_length; | 41 | unsigned short report_length; |
36 | 42 | ||
37 | /* recv report */ | 43 | /* recv report */ |
38 | char *set_report_buff; | 44 | struct list_head completed_out_req; |
39 | unsigned short set_report_length; | ||
40 | spinlock_t spinlock; | 45 | spinlock_t spinlock; |
41 | wait_queue_head_t read_queue; | 46 | wait_queue_head_t read_queue; |
47 | unsigned int qlen; | ||
42 | 48 | ||
43 | /* send report */ | 49 | /* send report */ |
44 | struct mutex lock; | 50 | struct mutex lock; |
@@ -49,7 +55,9 @@ struct f_hidg { | |||
49 | int minor; | 55 | int minor; |
50 | struct cdev cdev; | 56 | struct cdev cdev; |
51 | struct usb_function func; | 57 | struct usb_function func; |
58 | |||
52 | struct usb_ep *in_ep; | 59 | struct usb_ep *in_ep; |
60 | struct usb_ep *out_ep; | ||
53 | }; | 61 | }; |
54 | 62 | ||
55 | static inline struct f_hidg *func_to_hidg(struct usb_function *f) | 63 | static inline struct f_hidg *func_to_hidg(struct usb_function *f) |
@@ -65,7 +73,7 @@ static struct usb_interface_descriptor hidg_interface_desc = { | |||
65 | .bDescriptorType = USB_DT_INTERFACE, | 73 | .bDescriptorType = USB_DT_INTERFACE, |
66 | /* .bInterfaceNumber = DYNAMIC */ | 74 | /* .bInterfaceNumber = DYNAMIC */ |
67 | .bAlternateSetting = 0, | 75 | .bAlternateSetting = 0, |
68 | .bNumEndpoints = 1, | 76 | .bNumEndpoints = 2, |
69 | .bInterfaceClass = USB_CLASS_HID, | 77 | .bInterfaceClass = USB_CLASS_HID, |
70 | /* .bInterfaceSubClass = DYNAMIC */ | 78 | /* .bInterfaceSubClass = DYNAMIC */ |
71 | /* .bInterfaceProtocol = DYNAMIC */ | 79 | /* .bInterfaceProtocol = DYNAMIC */ |
@@ -96,10 +104,23 @@ static struct usb_endpoint_descriptor hidg_hs_in_ep_desc = { | |||
96 | */ | 104 | */ |
97 | }; | 105 | }; |
98 | 106 | ||
107 | static struct usb_endpoint_descriptor hidg_hs_out_ep_desc = { | ||
108 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
109 | .bDescriptorType = USB_DT_ENDPOINT, | ||
110 | .bEndpointAddress = USB_DIR_OUT, | ||
111 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
112 | /*.wMaxPacketSize = DYNAMIC */ | ||
113 | .bInterval = 4, /* FIXME: Add this field in the | ||
114 | * HID gadget configuration? | ||
115 | * (struct hidg_func_descriptor) | ||
116 | */ | ||
117 | }; | ||
118 | |||
99 | static struct usb_descriptor_header *hidg_hs_descriptors[] = { | 119 | static struct usb_descriptor_header *hidg_hs_descriptors[] = { |
100 | (struct usb_descriptor_header *)&hidg_interface_desc, | 120 | (struct usb_descriptor_header *)&hidg_interface_desc, |
101 | (struct usb_descriptor_header *)&hidg_desc, | 121 | (struct usb_descriptor_header *)&hidg_desc, |
102 | (struct usb_descriptor_header *)&hidg_hs_in_ep_desc, | 122 | (struct usb_descriptor_header *)&hidg_hs_in_ep_desc, |
123 | (struct usb_descriptor_header *)&hidg_hs_out_ep_desc, | ||
103 | NULL, | 124 | NULL, |
104 | }; | 125 | }; |
105 | 126 | ||
@@ -117,10 +138,23 @@ static struct usb_endpoint_descriptor hidg_fs_in_ep_desc = { | |||
117 | */ | 138 | */ |
118 | }; | 139 | }; |
119 | 140 | ||
141 | static struct usb_endpoint_descriptor hidg_fs_out_ep_desc = { | ||
142 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
143 | .bDescriptorType = USB_DT_ENDPOINT, | ||
144 | .bEndpointAddress = USB_DIR_OUT, | ||
145 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
146 | /*.wMaxPacketSize = DYNAMIC */ | ||
147 | .bInterval = 10, /* FIXME: Add this field in the | ||
148 | * HID gadget configuration? | ||
149 | * (struct hidg_func_descriptor) | ||
150 | */ | ||
151 | }; | ||
152 | |||
120 | static struct usb_descriptor_header *hidg_fs_descriptors[] = { | 153 | static struct usb_descriptor_header *hidg_fs_descriptors[] = { |
121 | (struct usb_descriptor_header *)&hidg_interface_desc, | 154 | (struct usb_descriptor_header *)&hidg_interface_desc, |
122 | (struct usb_descriptor_header *)&hidg_desc, | 155 | (struct usb_descriptor_header *)&hidg_desc, |
123 | (struct usb_descriptor_header *)&hidg_fs_in_ep_desc, | 156 | (struct usb_descriptor_header *)&hidg_fs_in_ep_desc, |
157 | (struct usb_descriptor_header *)&hidg_fs_out_ep_desc, | ||
124 | NULL, | 158 | NULL, |
125 | }; | 159 | }; |
126 | 160 | ||
@@ -130,9 +164,11 @@ static struct usb_descriptor_header *hidg_fs_descriptors[] = { | |||
130 | static ssize_t f_hidg_read(struct file *file, char __user *buffer, | 164 | static ssize_t f_hidg_read(struct file *file, char __user *buffer, |
131 | size_t count, loff_t *ptr) | 165 | size_t count, loff_t *ptr) |
132 | { | 166 | { |
133 | struct f_hidg *hidg = file->private_data; | 167 | struct f_hidg *hidg = file->private_data; |
134 | char *tmp_buff = NULL; | 168 | struct f_hidg_req_list *list; |
135 | unsigned long flags; | 169 | struct usb_request *req; |
170 | unsigned long flags; | ||
171 | int ret; | ||
136 | 172 | ||
137 | if (!count) | 173 | if (!count) |
138 | return 0; | 174 | return 0; |
@@ -142,8 +178,9 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer, | |||
142 | 178 | ||
143 | spin_lock_irqsave(&hidg->spinlock, flags); | 179 | spin_lock_irqsave(&hidg->spinlock, flags); |
144 | 180 | ||
145 | #define READ_COND (hidg->set_report_buff != NULL) | 181 | #define READ_COND (!list_empty(&hidg->completed_out_req)) |
146 | 182 | ||
183 | /* wait for at least one buffer to complete */ | ||
147 | while (!READ_COND) { | 184 | while (!READ_COND) { |
148 | spin_unlock_irqrestore(&hidg->spinlock, flags); | 185 | spin_unlock_irqrestore(&hidg->spinlock, flags); |
149 | if (file->f_flags & O_NONBLOCK) | 186 | if (file->f_flags & O_NONBLOCK) |
@@ -155,19 +192,34 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer, | |||
155 | spin_lock_irqsave(&hidg->spinlock, flags); | 192 | spin_lock_irqsave(&hidg->spinlock, flags); |
156 | } | 193 | } |
157 | 194 | ||
158 | 195 | /* pick the first one */ | |
159 | count = min_t(unsigned, count, hidg->set_report_length); | 196 | list = list_first_entry(&hidg->completed_out_req, |
160 | tmp_buff = hidg->set_report_buff; | 197 | struct f_hidg_req_list, list); |
161 | hidg->set_report_buff = NULL; | 198 | req = list->req; |
162 | 199 | count = min_t(unsigned int, count, req->actual - list->pos); | |
163 | spin_unlock_irqrestore(&hidg->spinlock, flags); | 200 | spin_unlock_irqrestore(&hidg->spinlock, flags); |
164 | 201 | ||
165 | if (tmp_buff != NULL) { | 202 | /* copy to user outside spinlock */ |
166 | /* copy to user outside spinlock */ | 203 | count -= copy_to_user(buffer, req->buf + list->pos, count); |
167 | count -= copy_to_user(buffer, tmp_buff, count); | 204 | list->pos += count; |
168 | kfree(tmp_buff); | 205 | |
169 | } else | 206 | /* |
170 | count = -ENOMEM; | 207 | * if this request is completely handled and transfered to |
208 | * userspace, remove its entry from the list and requeue it | ||
209 | * again. Otherwise, we will revisit it again upon the next | ||
210 | * call, taking into account its current read position. | ||
211 | */ | ||
212 | if (list->pos == req->actual) { | ||
213 | spin_lock_irqsave(&hidg->spinlock, flags); | ||
214 | list_del(&list->list); | ||
215 | kfree(list); | ||
216 | spin_unlock_irqrestore(&hidg->spinlock, flags); | ||
217 | |||
218 | req->length = hidg->report_length; | ||
219 | ret = usb_ep_queue(hidg->out_ep, req, GFP_KERNEL); | ||
220 | if (ret < 0) | ||
221 | return ret; | ||
222 | } | ||
171 | 223 | ||
172 | return count; | 224 | return count; |
173 | } | 225 | } |
@@ -282,28 +334,37 @@ static int f_hidg_open(struct inode *inode, struct file *fd) | |||
282 | /*-------------------------------------------------------------------------*/ | 334 | /*-------------------------------------------------------------------------*/ |
283 | /* usb_function */ | 335 | /* usb_function */ |
284 | 336 | ||
285 | static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req) | 337 | static struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep, unsigned length) |
286 | { | 338 | { |
287 | struct f_hidg *hidg = (struct f_hidg *)req->context; | 339 | struct usb_request *req; |
288 | 340 | ||
289 | if (req->status != 0 || req->buf == NULL || req->actual == 0) { | 341 | req = usb_ep_alloc_request(ep, GFP_ATOMIC); |
290 | ERROR(hidg->func.config->cdev, "%s FAILED\n", __func__); | 342 | if (req) { |
291 | return; | 343 | req->length = length; |
344 | req->buf = kmalloc(length, GFP_ATOMIC); | ||
345 | if (!req->buf) { | ||
346 | usb_ep_free_request(ep, req); | ||
347 | req = NULL; | ||
348 | } | ||
292 | } | 349 | } |
350 | return req; | ||
351 | } | ||
293 | 352 | ||
294 | spin_lock(&hidg->spinlock); | 353 | static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req) |
295 | 354 | { | |
296 | hidg->set_report_buff = krealloc(hidg->set_report_buff, | 355 | struct f_hidg *hidg = (struct f_hidg *) req->context; |
297 | req->actual, GFP_ATOMIC); | 356 | struct f_hidg_req_list *req_list; |
357 | unsigned long flags; | ||
298 | 358 | ||
299 | if (hidg->set_report_buff == NULL) { | 359 | req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC); |
300 | spin_unlock(&hidg->spinlock); | 360 | if (!req_list) |
301 | return; | 361 | return; |
302 | } | ||
303 | hidg->set_report_length = req->actual; | ||
304 | memcpy(hidg->set_report_buff, req->buf, req->actual); | ||
305 | 362 | ||
306 | spin_unlock(&hidg->spinlock); | 363 | req_list->req = req; |
364 | |||
365 | spin_lock_irqsave(&hidg->spinlock, flags); | ||
366 | list_add_tail(&req_list->list, &hidg->completed_out_req); | ||
367 | spin_unlock_irqrestore(&hidg->spinlock, flags); | ||
307 | 368 | ||
308 | wake_up(&hidg->read_queue); | 369 | wake_up(&hidg->read_queue); |
309 | } | 370 | } |
@@ -344,9 +405,7 @@ static int hidg_setup(struct usb_function *f, | |||
344 | case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | 405 | case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 |
345 | | HID_REQ_SET_REPORT): | 406 | | HID_REQ_SET_REPORT): |
346 | VDBG(cdev, "set_report | wLenght=%d\n", ctrl->wLength); | 407 | VDBG(cdev, "set_report | wLenght=%d\n", ctrl->wLength); |
347 | req->context = hidg; | 408 | goto stall; |
348 | req->complete = hidg_set_report_complete; | ||
349 | goto respond; | ||
350 | break; | 409 | break; |
351 | 410 | ||
352 | case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | 411 | case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 |
@@ -403,16 +462,25 @@ respond: | |||
403 | static void hidg_disable(struct usb_function *f) | 462 | static void hidg_disable(struct usb_function *f) |
404 | { | 463 | { |
405 | struct f_hidg *hidg = func_to_hidg(f); | 464 | struct f_hidg *hidg = func_to_hidg(f); |
465 | struct f_hidg_req_list *list, *next; | ||
406 | 466 | ||
407 | usb_ep_disable(hidg->in_ep); | 467 | usb_ep_disable(hidg->in_ep); |
408 | hidg->in_ep->driver_data = NULL; | 468 | hidg->in_ep->driver_data = NULL; |
469 | |||
470 | usb_ep_disable(hidg->out_ep); | ||
471 | hidg->out_ep->driver_data = NULL; | ||
472 | |||
473 | list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) { | ||
474 | list_del(&list->list); | ||
475 | kfree(list); | ||
476 | } | ||
409 | } | 477 | } |
410 | 478 | ||
411 | static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | 479 | static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) |
412 | { | 480 | { |
413 | struct usb_composite_dev *cdev = f->config->cdev; | 481 | struct usb_composite_dev *cdev = f->config->cdev; |
414 | struct f_hidg *hidg = func_to_hidg(f); | 482 | struct f_hidg *hidg = func_to_hidg(f); |
415 | int status = 0; | 483 | int i, status = 0; |
416 | 484 | ||
417 | VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt); | 485 | VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt); |
418 | 486 | ||
@@ -429,11 +497,55 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
429 | } | 497 | } |
430 | status = usb_ep_enable(hidg->in_ep); | 498 | status = usb_ep_enable(hidg->in_ep); |
431 | if (status < 0) { | 499 | if (status < 0) { |
432 | ERROR(cdev, "Enable endpoint FAILED!\n"); | 500 | ERROR(cdev, "Enable IN endpoint FAILED!\n"); |
433 | goto fail; | 501 | goto fail; |
434 | } | 502 | } |
435 | hidg->in_ep->driver_data = hidg; | 503 | hidg->in_ep->driver_data = hidg; |
436 | } | 504 | } |
505 | |||
506 | |||
507 | if (hidg->out_ep != NULL) { | ||
508 | /* restart endpoint */ | ||
509 | if (hidg->out_ep->driver_data != NULL) | ||
510 | usb_ep_disable(hidg->out_ep); | ||
511 | |||
512 | status = config_ep_by_speed(f->config->cdev->gadget, f, | ||
513 | hidg->out_ep); | ||
514 | if (status) { | ||
515 | ERROR(cdev, "config_ep_by_speed FAILED!\n"); | ||
516 | goto fail; | ||
517 | } | ||
518 | status = usb_ep_enable(hidg->out_ep); | ||
519 | if (status < 0) { | ||
520 | ERROR(cdev, "Enable IN endpoint FAILED!\n"); | ||
521 | goto fail; | ||
522 | } | ||
523 | hidg->out_ep->driver_data = hidg; | ||
524 | |||
525 | /* | ||
526 | * allocate a bunch of read buffers and queue them all at once. | ||
527 | */ | ||
528 | for (i = 0; i < hidg->qlen && status == 0; i++) { | ||
529 | struct usb_request *req = | ||
530 | hidg_alloc_ep_req(hidg->out_ep, | ||
531 | hidg->report_length); | ||
532 | if (req) { | ||
533 | req->complete = hidg_set_report_complete; | ||
534 | req->context = hidg; | ||
535 | status = usb_ep_queue(hidg->out_ep, req, | ||
536 | GFP_ATOMIC); | ||
537 | if (status) | ||
538 | ERROR(cdev, "%s queue req --> %d\n", | ||
539 | hidg->out_ep->name, status); | ||
540 | } else { | ||
541 | usb_ep_disable(hidg->out_ep); | ||
542 | hidg->out_ep->driver_data = NULL; | ||
543 | status = -ENOMEM; | ||
544 | goto fail; | ||
545 | } | ||
546 | } | ||
547 | } | ||
548 | |||
437 | fail: | 549 | fail: |
438 | return status; | 550 | return status; |
439 | } | 551 | } |
@@ -470,13 +582,18 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) | |||
470 | ep->driver_data = c->cdev; /* claim */ | 582 | ep->driver_data = c->cdev; /* claim */ |
471 | hidg->in_ep = ep; | 583 | hidg->in_ep = ep; |
472 | 584 | ||
585 | ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc); | ||
586 | if (!ep) | ||
587 | goto fail; | ||
588 | ep->driver_data = c->cdev; /* claim */ | ||
589 | hidg->out_ep = ep; | ||
590 | |||
473 | /* preallocate request and buffer */ | 591 | /* preallocate request and buffer */ |
474 | status = -ENOMEM; | 592 | status = -ENOMEM; |
475 | hidg->req = usb_ep_alloc_request(hidg->in_ep, GFP_KERNEL); | 593 | hidg->req = usb_ep_alloc_request(hidg->in_ep, GFP_KERNEL); |
476 | if (!hidg->req) | 594 | if (!hidg->req) |
477 | goto fail; | 595 | goto fail; |
478 | 596 | ||
479 | |||
480 | hidg->req->buf = kmalloc(hidg->report_length, GFP_KERNEL); | 597 | hidg->req->buf = kmalloc(hidg->report_length, GFP_KERNEL); |
481 | if (!hidg->req->buf) | 598 | if (!hidg->req->buf) |
482 | goto fail; | 599 | goto fail; |
@@ -486,12 +603,12 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) | |||
486 | hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; | 603 | hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; |
487 | hidg_hs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); | 604 | hidg_hs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); |
488 | hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); | 605 | hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); |
606 | hidg_hs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); | ||
607 | hidg_fs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); | ||
489 | hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT; | 608 | hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT; |
490 | hidg_desc.desc[0].wDescriptorLength = | 609 | hidg_desc.desc[0].wDescriptorLength = |
491 | cpu_to_le16(hidg->report_desc_length); | 610 | cpu_to_le16(hidg->report_desc_length); |
492 | 611 | ||
493 | hidg->set_report_buff = NULL; | ||
494 | |||
495 | /* copy descriptors */ | 612 | /* copy descriptors */ |
496 | f->descriptors = usb_copy_descriptors(hidg_fs_descriptors); | 613 | f->descriptors = usb_copy_descriptors(hidg_fs_descriptors); |
497 | if (!f->descriptors) | 614 | if (!f->descriptors) |
@@ -500,6 +617,8 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) | |||
500 | if (gadget_is_dualspeed(c->cdev->gadget)) { | 617 | if (gadget_is_dualspeed(c->cdev->gadget)) { |
501 | hidg_hs_in_ep_desc.bEndpointAddress = | 618 | hidg_hs_in_ep_desc.bEndpointAddress = |
502 | hidg_fs_in_ep_desc.bEndpointAddress; | 619 | hidg_fs_in_ep_desc.bEndpointAddress; |
620 | hidg_hs_out_ep_desc.bEndpointAddress = | ||
621 | hidg_fs_out_ep_desc.bEndpointAddress; | ||
503 | f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors); | 622 | f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors); |
504 | if (!f->hs_descriptors) | 623 | if (!f->hs_descriptors) |
505 | goto fail; | 624 | goto fail; |
@@ -509,6 +628,7 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) | |||
509 | spin_lock_init(&hidg->spinlock); | 628 | spin_lock_init(&hidg->spinlock); |
510 | init_waitqueue_head(&hidg->write_queue); | 629 | init_waitqueue_head(&hidg->write_queue); |
511 | init_waitqueue_head(&hidg->read_queue); | 630 | init_waitqueue_head(&hidg->read_queue); |
631 | INIT_LIST_HEAD(&hidg->completed_out_req); | ||
512 | 632 | ||
513 | /* create char device */ | 633 | /* create char device */ |
514 | cdev_init(&hidg->cdev, &f_hidg_fops); | 634 | cdev_init(&hidg->cdev, &f_hidg_fops); |
@@ -553,7 +673,6 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) | |||
553 | usb_free_descriptors(f->descriptors); | 673 | usb_free_descriptors(f->descriptors); |
554 | 674 | ||
555 | kfree(hidg->report_desc); | 675 | kfree(hidg->report_desc); |
556 | kfree(hidg->set_report_buff); | ||
557 | kfree(hidg); | 676 | kfree(hidg); |
558 | } | 677 | } |
559 | 678 | ||
@@ -624,6 +743,9 @@ int __init hidg_bind_config(struct usb_configuration *c, | |||
624 | hidg->func.disable = hidg_disable; | 743 | hidg->func.disable = hidg_disable; |
625 | hidg->func.setup = hidg_setup; | 744 | hidg->func.setup = hidg_setup; |
626 | 745 | ||
746 | /* this could me made configurable at some point */ | ||
747 | hidg->qlen = 4; | ||
748 | |||
627 | status = usb_add_function(c, &hidg->func); | 749 | status = usb_add_function(c, &hidg->func); |
628 | if (status) | 750 | if (status) |
629 | kfree(hidg); | 751 | kfree(hidg); |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index f67b453740bd..4f1142efa6d1 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -44,12 +44,12 @@ | |||
44 | * function for a USB device, it also illustrates a technique of | 44 | * function for a USB device, it also illustrates a technique of |
45 | * double-buffering for increased throughput. | 45 | * double-buffering for increased throughput. |
46 | * | 46 | * |
47 | * Function supports multiple logical units (LUNs). Backing storage | 47 | * For more information about MSF and in particular its module |
48 | * for each LUN is provided by a regular file or a block device. | 48 | * parameters and sysfs interface read the |
49 | * Access for each LUN can be limited to read-only. Moreover, the | 49 | * <Documentation/usb/mass-storage.txt> file. |
50 | * function can indicate that LUN is removable and/or CD-ROM. (The | 50 | */ |
51 | * later implies read-only access.) | 51 | |
52 | * | 52 | /* |
53 | * MSF is configured by specifying a fsg_config structure. It has the | 53 | * MSF is configured by specifying a fsg_config structure. It has the |
54 | * following fields: | 54 | * following fields: |
55 | * | 55 | * |
@@ -75,25 +75,6 @@ | |||
75 | * ->nofua Flag specifying that FUA flag in SCSI WRITE(10,12) | 75 | * ->nofua Flag specifying that FUA flag in SCSI WRITE(10,12) |
76 | * commands for this LUN shall be ignored. | 76 | * commands for this LUN shall be ignored. |
77 | * | 77 | * |
78 | * lun_name_format A printf-like format for names of the LUN | ||
79 | * devices. This determines how the | ||
80 | * directory in sysfs will be named. | ||
81 | * Unless you are using several MSFs in | ||
82 | * a single gadget (as opposed to single | ||
83 | * MSF in many configurations) you may | ||
84 | * leave it as NULL (in which case | ||
85 | * "lun%d" will be used). In the format | ||
86 | * you can use "%d" to index LUNs for | ||
87 | * MSF's with more than one LUN. (Beware | ||
88 | * that there is only one integer given | ||
89 | * as an argument for the format and | ||
90 | * specifying invalid format may cause | ||
91 | * unspecified behaviour.) | ||
92 | * thread_name Name of the kernel thread process used by the | ||
93 | * MSF. You can safely set it to NULL | ||
94 | * (in which case default "file-storage" | ||
95 | * will be used). | ||
96 | * | ||
97 | * vendor_name | 78 | * vendor_name |
98 | * product_name | 79 | * product_name |
99 | * release Information used as a reply to INQUIRY | 80 | * release Information used as a reply to INQUIRY |
@@ -114,62 +95,6 @@ | |||
114 | * data track and no audio tracks; hence there need be only one | 95 | * data track and no audio tracks; hence there need be only one |
115 | * backing file per LUN. | 96 | * backing file per LUN. |
116 | * | 97 | * |
117 | * | ||
118 | * MSF includes support for module parameters. If gadget using it | ||
119 | * decides to use it, the following module parameters will be | ||
120 | * available: | ||
121 | * | ||
122 | * file=filename[,filename...] | ||
123 | * Names of the files or block devices used for | ||
124 | * backing storage. | ||
125 | * ro=b[,b...] Default false, boolean for read-only access. | ||
126 | * removable=b[,b...] | ||
127 | * Default true, boolean for removable media. | ||
128 | * cdrom=b[,b...] Default false, boolean for whether to emulate | ||
129 | * a CD-ROM drive. | ||
130 | * nofua=b[,b...] Default false, booleans for ignore FUA flag | ||
131 | * in SCSI WRITE(10,12) commands | ||
132 | * luns=N Default N = number of filenames, number of | ||
133 | * LUNs to support. | ||
134 | * stall Default determined according to the type of | ||
135 | * USB device controller (usually true), | ||
136 | * boolean to permit the driver to halt | ||
137 | * bulk endpoints. | ||
138 | * | ||
139 | * The module parameters may be prefixed with some string. You need | ||
140 | * to consult gadget's documentation or source to verify whether it is | ||
141 | * using those module parameters and if it does what are the prefixes | ||
142 | * (look for FSG_MODULE_PARAMETERS() macro usage, what's inside it is | ||
143 | * the prefix). | ||
144 | * | ||
145 | * | ||
146 | * Requirements are modest; only a bulk-in and a bulk-out endpoint are | ||
147 | * needed. The memory requirement amounts to two 16K buffers, size | ||
148 | * configurable by a parameter. Support is included for both | ||
149 | * full-speed and high-speed operation. | ||
150 | * | ||
151 | * Note that the driver is slightly non-portable in that it assumes a | ||
152 | * single memory/DMA buffer will be useable for bulk-in, bulk-out, and | ||
153 | * interrupt-in endpoints. With most device controllers this isn't an | ||
154 | * issue, but there may be some with hardware restrictions that prevent | ||
155 | * a buffer from being used by more than one endpoint. | ||
156 | * | ||
157 | * | ||
158 | * The pathnames of the backing files and the ro settings are | ||
159 | * available in the attribute files "file" and "ro" in the lun<n> (or | ||
160 | * to be more precise in a directory which name comes from | ||
161 | * "lun_name_format" option!) subdirectory of the gadget's sysfs | ||
162 | * directory. If the "removable" option is set, writing to these | ||
163 | * files will simulate ejecting/loading the medium (writing an empty | ||
164 | * line means eject) and adjusting a write-enable tab. Changes to the | ||
165 | * ro setting are not allowed when the medium is loaded or if CD-ROM | ||
166 | * emulation is being used. | ||
167 | * | ||
168 | * When a LUN receive an "eject" SCSI request (Start/Stop Unit), | ||
169 | * if the LUN is removable, the backing file is released to simulate | ||
170 | * ejection. | ||
171 | * | ||
172 | * | ||
173 | * This function is heavily based on "File-backed Storage Gadget" by | 98 | * This function is heavily based on "File-backed Storage Gadget" by |
174 | * Alan Stern which in turn is heavily based on "Gadget Zero" by David | 99 | * Alan Stern which in turn is heavily based on "Gadget Zero" by David |
175 | * Brownell. The driver's SCSI command interface was based on the | 100 | * Brownell. The driver's SCSI command interface was based on the |
@@ -211,7 +136,7 @@ | |||
211 | * In normal operation the main thread is started during the gadget's | 136 | * In normal operation the main thread is started during the gadget's |
212 | * fsg_bind() callback and stopped during fsg_unbind(). But it can | 137 | * fsg_bind() callback and stopped during fsg_unbind(). But it can |
213 | * also exit when it receives a signal, and there's no point leaving | 138 | * also exit when it receives a signal, and there's no point leaving |
214 | * the gadget running when the thread is dead. At of this moment, MSF | 139 | * the gadget running when the thread is dead. As of this moment, MSF |
215 | * provides no way to deregister the gadget when thread dies -- maybe | 140 | * provides no way to deregister the gadget when thread dies -- maybe |
216 | * a callback functions is needed. | 141 | * a callback functions is needed. |
217 | * | 142 | * |
@@ -417,9 +342,6 @@ struct fsg_config { | |||
417 | char nofua; | 342 | char nofua; |
418 | } luns[FSG_MAX_LUNS]; | 343 | } luns[FSG_MAX_LUNS]; |
419 | 344 | ||
420 | const char *lun_name_format; | ||
421 | const char *thread_name; | ||
422 | |||
423 | /* Callback functions. */ | 345 | /* Callback functions. */ |
424 | const struct fsg_operations *ops; | 346 | const struct fsg_operations *ops; |
425 | /* Gadget's private data. */ | 347 | /* Gadget's private data. */ |
@@ -2687,11 +2609,15 @@ static int fsg_main_thread(void *common_) | |||
2687 | 2609 | ||
2688 | /*************************** DEVICE ATTRIBUTES ***************************/ | 2610 | /*************************** DEVICE ATTRIBUTES ***************************/ |
2689 | 2611 | ||
2690 | /* Write permission is checked per LUN in store_*() functions. */ | ||
2691 | static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro); | 2612 | static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro); |
2692 | static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua); | 2613 | static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua); |
2693 | static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file); | 2614 | static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file); |
2694 | 2615 | ||
2616 | static struct device_attribute dev_attr_ro_cdrom = | ||
2617 | __ATTR(ro, 0444, fsg_show_ro, NULL); | ||
2618 | static struct device_attribute dev_attr_file_nonremovable = | ||
2619 | __ATTR(file, 0444, fsg_show_file, NULL); | ||
2620 | |||
2695 | 2621 | ||
2696 | /****************************** FSG COMMON ******************************/ | 2622 | /****************************** FSG COMMON ******************************/ |
2697 | 2623 | ||
@@ -2792,11 +2718,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2792 | curlun->dev.parent = &gadget->dev; | 2718 | curlun->dev.parent = &gadget->dev; |
2793 | /* curlun->dev.driver = &fsg_driver.driver; XXX */ | 2719 | /* curlun->dev.driver = &fsg_driver.driver; XXX */ |
2794 | dev_set_drvdata(&curlun->dev, &common->filesem); | 2720 | dev_set_drvdata(&curlun->dev, &common->filesem); |
2795 | dev_set_name(&curlun->dev, | 2721 | dev_set_name(&curlun->dev, "lun%d", i); |
2796 | cfg->lun_name_format | ||
2797 | ? cfg->lun_name_format | ||
2798 | : "lun%d", | ||
2799 | i); | ||
2800 | 2722 | ||
2801 | rc = device_register(&curlun->dev); | 2723 | rc = device_register(&curlun->dev); |
2802 | if (rc) { | 2724 | if (rc) { |
@@ -2806,10 +2728,16 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2806 | goto error_release; | 2728 | goto error_release; |
2807 | } | 2729 | } |
2808 | 2730 | ||
2809 | rc = device_create_file(&curlun->dev, &dev_attr_ro); | 2731 | rc = device_create_file(&curlun->dev, |
2732 | curlun->cdrom | ||
2733 | ? &dev_attr_ro_cdrom | ||
2734 | : &dev_attr_ro); | ||
2810 | if (rc) | 2735 | if (rc) |
2811 | goto error_luns; | 2736 | goto error_luns; |
2812 | rc = device_create_file(&curlun->dev, &dev_attr_file); | 2737 | rc = device_create_file(&curlun->dev, |
2738 | curlun->removable | ||
2739 | ? &dev_attr_file | ||
2740 | : &dev_attr_file_nonremovable); | ||
2813 | if (rc) | 2741 | if (rc) |
2814 | goto error_luns; | 2742 | goto error_luns; |
2815 | rc = device_create_file(&curlun->dev, &dev_attr_nofua); | 2743 | rc = device_create_file(&curlun->dev, &dev_attr_nofua); |
@@ -2878,8 +2806,7 @@ buffhds_first_it: | |||
2878 | 2806 | ||
2879 | /* Tell the thread to start working */ | 2807 | /* Tell the thread to start working */ |
2880 | common->thread_task = | 2808 | common->thread_task = |
2881 | kthread_create(fsg_main_thread, common, | 2809 | kthread_create(fsg_main_thread, common, "file-storage"); |
2882 | cfg->thread_name ?: "file-storage"); | ||
2883 | if (IS_ERR(common->thread_task)) { | 2810 | if (IS_ERR(common->thread_task)) { |
2884 | rc = PTR_ERR(common->thread_task); | 2811 | rc = PTR_ERR(common->thread_task); |
2885 | goto error_release; | 2812 | goto error_release; |
@@ -2945,8 +2872,14 @@ static void fsg_common_release(struct kref *ref) | |||
2945 | /* In error recovery common->nluns may be zero. */ | 2872 | /* In error recovery common->nluns may be zero. */ |
2946 | for (; i; --i, ++lun) { | 2873 | for (; i; --i, ++lun) { |
2947 | device_remove_file(&lun->dev, &dev_attr_nofua); | 2874 | device_remove_file(&lun->dev, &dev_attr_nofua); |
2948 | device_remove_file(&lun->dev, &dev_attr_ro); | 2875 | device_remove_file(&lun->dev, |
2949 | device_remove_file(&lun->dev, &dev_attr_file); | 2876 | lun->cdrom |
2877 | ? &dev_attr_ro_cdrom | ||
2878 | : &dev_attr_ro); | ||
2879 | device_remove_file(&lun->dev, | ||
2880 | lun->removable | ||
2881 | ? &dev_attr_file | ||
2882 | : &dev_attr_file_nonremovable); | ||
2950 | fsg_lun_close(lun); | 2883 | fsg_lun_close(lun); |
2951 | device_unregister(&lun->dev); | 2884 | device_unregister(&lun->dev); |
2952 | } | 2885 | } |
@@ -3167,8 +3100,7 @@ fsg_config_from_params(struct fsg_config *cfg, | |||
3167 | for (i = 0, lun = cfg->luns; i < cfg->nluns; ++i, ++lun) { | 3100 | for (i = 0, lun = cfg->luns; i < cfg->nluns; ++i, ++lun) { |
3168 | lun->ro = !!params->ro[i]; | 3101 | lun->ro = !!params->ro[i]; |
3169 | lun->cdrom = !!params->cdrom[i]; | 3102 | lun->cdrom = !!params->cdrom[i]; |
3170 | lun->removable = /* Removable by default */ | 3103 | lun->removable = !!params->removable[i]; |
3171 | params->removable_count <= i || params->removable[i]; | ||
3172 | lun->filename = | 3104 | lun->filename = |
3173 | params->file_count > i && params->file[i][0] | 3105 | params->file_count > i && params->file[i][0] |
3174 | ? params->file[i] | 3106 | ? params->file[i] |
@@ -3176,8 +3108,6 @@ fsg_config_from_params(struct fsg_config *cfg, | |||
3176 | } | 3108 | } |
3177 | 3109 | ||
3178 | /* Let MSF use defaults */ | 3110 | /* Let MSF use defaults */ |
3179 | cfg->lun_name_format = 0; | ||
3180 | cfg->thread_name = 0; | ||
3181 | cfg->vendor_name = 0; | 3111 | cfg->vendor_name = 0; |
3182 | cfg->product_name = 0; | 3112 | cfg->product_name = 0; |
3183 | cfg->release = 0xffff; | 3113 | cfg->release = 0xffff; |
@@ -3203,4 +3133,3 @@ fsg_common_from_params(struct fsg_common *common, | |||
3203 | fsg_config_from_params(&cfg, params); | 3133 | fsg_config_from_params(&cfg, params); |
3204 | return fsg_common_init(common, cdev, &cfg); | 3134 | return fsg_common_init(common, cdev, &cfg); |
3205 | } | 3135 | } |
3206 | |||
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 2022fe492148..2a8bf0655c60 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c | |||
@@ -29,6 +29,25 @@ | |||
29 | 29 | ||
30 | unsigned int uvc_gadget_trace_param; | 30 | unsigned int uvc_gadget_trace_param; |
31 | 31 | ||
32 | /*-------------------------------------------------------------------------*/ | ||
33 | |||
34 | /* module parameters specific to the Video streaming endpoint */ | ||
35 | static unsigned streaming_interval = 1; | ||
36 | module_param(streaming_interval, uint, S_IRUGO|S_IWUSR); | ||
37 | MODULE_PARM_DESC(streaming_interval, "1 - 16"); | ||
38 | |||
39 | static unsigned streaming_maxpacket = 1024; | ||
40 | module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR); | ||
41 | MODULE_PARM_DESC(streaming_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)"); | ||
42 | |||
43 | static unsigned streaming_mult; | ||
44 | module_param(streaming_mult, uint, S_IRUGO|S_IWUSR); | ||
45 | MODULE_PARM_DESC(streaming_mult, "0 - 2 (hs/ss only)"); | ||
46 | |||
47 | static unsigned streaming_maxburst; | ||
48 | module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR); | ||
49 | MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)"); | ||
50 | |||
32 | /* -------------------------------------------------------------------------- | 51 | /* -------------------------------------------------------------------------- |
33 | * Function descriptors | 52 | * Function descriptors |
34 | */ | 53 | */ |
@@ -59,6 +78,8 @@ static struct usb_gadget_strings *uvc_function_strings[] = { | |||
59 | #define UVC_INTF_VIDEO_CONTROL 0 | 78 | #define UVC_INTF_VIDEO_CONTROL 0 |
60 | #define UVC_INTF_VIDEO_STREAMING 1 | 79 | #define UVC_INTF_VIDEO_STREAMING 1 |
61 | 80 | ||
81 | #define STATUS_BYTECOUNT 16 /* 16 bytes status */ | ||
82 | |||
62 | static struct usb_interface_assoc_descriptor uvc_iad __initdata = { | 83 | static struct usb_interface_assoc_descriptor uvc_iad __initdata = { |
63 | .bLength = sizeof(uvc_iad), | 84 | .bLength = sizeof(uvc_iad), |
64 | .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, | 85 | .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, |
@@ -82,12 +103,12 @@ static struct usb_interface_descriptor uvc_control_intf __initdata = { | |||
82 | .iInterface = 0, | 103 | .iInterface = 0, |
83 | }; | 104 | }; |
84 | 105 | ||
85 | static struct usb_endpoint_descriptor uvc_control_ep __initdata = { | 106 | static struct usb_endpoint_descriptor uvc_fs_control_ep __initdata = { |
86 | .bLength = USB_DT_ENDPOINT_SIZE, | 107 | .bLength = USB_DT_ENDPOINT_SIZE, |
87 | .bDescriptorType = USB_DT_ENDPOINT, | 108 | .bDescriptorType = USB_DT_ENDPOINT, |
88 | .bEndpointAddress = USB_DIR_IN, | 109 | .bEndpointAddress = USB_DIR_IN, |
89 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 110 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
90 | .wMaxPacketSize = cpu_to_le16(16), | 111 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), |
91 | .bInterval = 8, | 112 | .bInterval = 8, |
92 | }; | 113 | }; |
93 | 114 | ||
@@ -95,7 +116,7 @@ static struct uvc_control_endpoint_descriptor uvc_control_cs_ep __initdata = { | |||
95 | .bLength = UVC_DT_CONTROL_ENDPOINT_SIZE, | 116 | .bLength = UVC_DT_CONTROL_ENDPOINT_SIZE, |
96 | .bDescriptorType = USB_DT_CS_ENDPOINT, | 117 | .bDescriptorType = USB_DT_CS_ENDPOINT, |
97 | .bDescriptorSubType = UVC_EP_INTERRUPT, | 118 | .bDescriptorSubType = UVC_EP_INTERRUPT, |
98 | .wMaxTransferSize = cpu_to_le16(16), | 119 | .wMaxTransferSize = cpu_to_le16(STATUS_BYTECOUNT), |
99 | }; | 120 | }; |
100 | 121 | ||
101 | static struct usb_interface_descriptor uvc_streaming_intf_alt0 __initdata = { | 122 | static struct usb_interface_descriptor uvc_streaming_intf_alt0 __initdata = { |
@@ -122,7 +143,7 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt1 __initdata = { | |||
122 | .iInterface = 0, | 143 | .iInterface = 0, |
123 | }; | 144 | }; |
124 | 145 | ||
125 | static struct usb_endpoint_descriptor uvc_streaming_ep = { | 146 | static struct usb_endpoint_descriptor uvc_fs_streaming_ep = { |
126 | .bLength = USB_DT_ENDPOINT_SIZE, | 147 | .bLength = USB_DT_ENDPOINT_SIZE, |
127 | .bDescriptorType = USB_DT_ENDPOINT, | 148 | .bDescriptorType = USB_DT_ENDPOINT, |
128 | .bEndpointAddress = USB_DIR_IN, | 149 | .bEndpointAddress = USB_DIR_IN, |
@@ -131,15 +152,72 @@ static struct usb_endpoint_descriptor uvc_streaming_ep = { | |||
131 | .bInterval = 1, | 152 | .bInterval = 1, |
132 | }; | 153 | }; |
133 | 154 | ||
155 | static struct usb_endpoint_descriptor uvc_hs_streaming_ep = { | ||
156 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
157 | .bDescriptorType = USB_DT_ENDPOINT, | ||
158 | .bEndpointAddress = USB_DIR_IN, | ||
159 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, | ||
160 | .wMaxPacketSize = cpu_to_le16(1024), | ||
161 | .bInterval = 1, | ||
162 | }; | ||
163 | |||
164 | /* super speed support */ | ||
165 | static struct usb_endpoint_descriptor uvc_ss_control_ep __initdata = { | ||
166 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
167 | .bDescriptorType = USB_DT_ENDPOINT, | ||
168 | |||
169 | .bEndpointAddress = USB_DIR_IN, | ||
170 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
171 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), | ||
172 | .bInterval = 8, | ||
173 | }; | ||
174 | |||
175 | static struct usb_ss_ep_comp_descriptor uvc_ss_control_comp __initdata = { | ||
176 | .bLength = sizeof uvc_ss_control_comp, | ||
177 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
178 | |||
179 | /* the following 3 values can be tweaked if necessary */ | ||
180 | /* .bMaxBurst = 0, */ | ||
181 | /* .bmAttributes = 0, */ | ||
182 | .wBytesPerInterval = cpu_to_le16(STATUS_BYTECOUNT), | ||
183 | }; | ||
184 | |||
185 | static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = { | ||
186 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
187 | .bDescriptorType = USB_DT_ENDPOINT, | ||
188 | |||
189 | .bEndpointAddress = USB_DIR_IN, | ||
190 | .bmAttributes = USB_ENDPOINT_XFER_ISOC, | ||
191 | .wMaxPacketSize = cpu_to_le16(1024), | ||
192 | .bInterval = 4, | ||
193 | }; | ||
194 | |||
195 | static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = { | ||
196 | .bLength = sizeof uvc_ss_streaming_comp, | ||
197 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
198 | |||
199 | /* the following 3 values can be tweaked if necessary */ | ||
200 | .bMaxBurst = 0, | ||
201 | .bmAttributes = 0, | ||
202 | .wBytesPerInterval = cpu_to_le16(1024), | ||
203 | }; | ||
204 | |||
134 | static const struct usb_descriptor_header * const uvc_fs_streaming[] = { | 205 | static const struct usb_descriptor_header * const uvc_fs_streaming[] = { |
135 | (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, | 206 | (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, |
136 | (struct usb_descriptor_header *) &uvc_streaming_ep, | 207 | (struct usb_descriptor_header *) &uvc_fs_streaming_ep, |
137 | NULL, | 208 | NULL, |
138 | }; | 209 | }; |
139 | 210 | ||
140 | static const struct usb_descriptor_header * const uvc_hs_streaming[] = { | 211 | static const struct usb_descriptor_header * const uvc_hs_streaming[] = { |
141 | (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, | 212 | (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, |
142 | (struct usb_descriptor_header *) &uvc_streaming_ep, | 213 | (struct usb_descriptor_header *) &uvc_hs_streaming_ep, |
214 | NULL, | ||
215 | }; | ||
216 | |||
217 | static const struct usb_descriptor_header * const uvc_ss_streaming[] = { | ||
218 | (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, | ||
219 | (struct usb_descriptor_header *) &uvc_ss_streaming_ep, | ||
220 | (struct usb_descriptor_header *) &uvc_ss_streaming_comp, | ||
143 | NULL, | 221 | NULL, |
144 | }; | 222 | }; |
145 | 223 | ||
@@ -215,6 +293,7 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) | |||
215 | struct uvc_device *uvc = to_uvc(f); | 293 | struct uvc_device *uvc = to_uvc(f); |
216 | struct v4l2_event v4l2_event; | 294 | struct v4l2_event v4l2_event; |
217 | struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; | 295 | struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; |
296 | int ret; | ||
218 | 297 | ||
219 | INFO(f->config->cdev, "uvc_function_set_alt(%u, %u)\n", interface, alt); | 298 | INFO(f->config->cdev, "uvc_function_set_alt(%u, %u)\n", interface, alt); |
220 | 299 | ||
@@ -262,7 +341,10 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) | |||
262 | return 0; | 341 | return 0; |
263 | 342 | ||
264 | if (uvc->video.ep) { | 343 | if (uvc->video.ep) { |
265 | uvc->video.ep->desc = &uvc_streaming_ep; | 344 | ret = config_ep_by_speed(f->config->cdev->gadget, |
345 | &(uvc->func), uvc->video.ep); | ||
346 | if (ret) | ||
347 | return ret; | ||
266 | usb_ep_enable(uvc->video.ep); | 348 | usb_ep_enable(uvc->video.ep); |
267 | } | 349 | } |
268 | 350 | ||
@@ -368,9 +450,11 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) | |||
368 | { | 450 | { |
369 | struct uvc_input_header_descriptor *uvc_streaming_header; | 451 | struct uvc_input_header_descriptor *uvc_streaming_header; |
370 | struct uvc_header_descriptor *uvc_control_header; | 452 | struct uvc_header_descriptor *uvc_control_header; |
453 | const struct uvc_descriptor_header * const *uvc_control_desc; | ||
371 | const struct uvc_descriptor_header * const *uvc_streaming_cls; | 454 | const struct uvc_descriptor_header * const *uvc_streaming_cls; |
372 | const struct usb_descriptor_header * const *uvc_streaming_std; | 455 | const struct usb_descriptor_header * const *uvc_streaming_std; |
373 | const struct usb_descriptor_header * const *src; | 456 | const struct usb_descriptor_header * const *src; |
457 | static struct usb_endpoint_descriptor *uvc_control_ep; | ||
374 | struct usb_descriptor_header **dst; | 458 | struct usb_descriptor_header **dst; |
375 | struct usb_descriptor_header **hdr; | 459 | struct usb_descriptor_header **hdr; |
376 | unsigned int control_size; | 460 | unsigned int control_size; |
@@ -379,10 +463,29 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) | |||
379 | unsigned int bytes; | 463 | unsigned int bytes; |
380 | void *mem; | 464 | void *mem; |
381 | 465 | ||
382 | uvc_streaming_cls = (speed == USB_SPEED_FULL) | 466 | switch (speed) { |
383 | ? uvc->desc.fs_streaming : uvc->desc.hs_streaming; | 467 | case USB_SPEED_SUPER: |
384 | uvc_streaming_std = (speed == USB_SPEED_FULL) | 468 | uvc_control_desc = uvc->desc.ss_control; |
385 | ? uvc_fs_streaming : uvc_hs_streaming; | 469 | uvc_streaming_cls = uvc->desc.ss_streaming; |
470 | uvc_streaming_std = uvc_ss_streaming; | ||
471 | uvc_control_ep = &uvc_ss_control_ep; | ||
472 | break; | ||
473 | |||
474 | case USB_SPEED_HIGH: | ||
475 | uvc_control_desc = uvc->desc.fs_control; | ||
476 | uvc_streaming_cls = uvc->desc.hs_streaming; | ||
477 | uvc_streaming_std = uvc_hs_streaming; | ||
478 | uvc_control_ep = &uvc_fs_control_ep; | ||
479 | break; | ||
480 | |||
481 | case USB_SPEED_FULL: | ||
482 | default: | ||
483 | uvc_control_desc = uvc->desc.fs_control; | ||
484 | uvc_streaming_cls = uvc->desc.fs_streaming; | ||
485 | uvc_streaming_std = uvc_fs_streaming; | ||
486 | uvc_control_ep = &uvc_fs_control_ep; | ||
487 | break; | ||
488 | } | ||
386 | 489 | ||
387 | /* Descriptors layout | 490 | /* Descriptors layout |
388 | * | 491 | * |
@@ -400,16 +503,24 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) | |||
400 | control_size = 0; | 503 | control_size = 0; |
401 | streaming_size = 0; | 504 | streaming_size = 0; |
402 | bytes = uvc_iad.bLength + uvc_control_intf.bLength | 505 | bytes = uvc_iad.bLength + uvc_control_intf.bLength |
403 | + uvc_control_ep.bLength + uvc_control_cs_ep.bLength | 506 | + uvc_control_ep->bLength + uvc_control_cs_ep.bLength |
404 | + uvc_streaming_intf_alt0.bLength; | 507 | + uvc_streaming_intf_alt0.bLength; |
405 | n_desc = 5; | ||
406 | 508 | ||
407 | for (src = (const struct usb_descriptor_header**)uvc->desc.control; *src; ++src) { | 509 | if (speed == USB_SPEED_SUPER) { |
510 | bytes += uvc_ss_control_comp.bLength; | ||
511 | n_desc = 6; | ||
512 | } else { | ||
513 | n_desc = 5; | ||
514 | } | ||
515 | |||
516 | for (src = (const struct usb_descriptor_header **)uvc_control_desc; | ||
517 | *src; ++src) { | ||
408 | control_size += (*src)->bLength; | 518 | control_size += (*src)->bLength; |
409 | bytes += (*src)->bLength; | 519 | bytes += (*src)->bLength; |
410 | n_desc++; | 520 | n_desc++; |
411 | } | 521 | } |
412 | for (src = (const struct usb_descriptor_header**)uvc_streaming_cls; *src; ++src) { | 522 | for (src = (const struct usb_descriptor_header **)uvc_streaming_cls; |
523 | *src; ++src) { | ||
413 | streaming_size += (*src)->bLength; | 524 | streaming_size += (*src)->bLength; |
414 | bytes += (*src)->bLength; | 525 | bytes += (*src)->bLength; |
415 | n_desc++; | 526 | n_desc++; |
@@ -433,12 +544,15 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) | |||
433 | 544 | ||
434 | uvc_control_header = mem; | 545 | uvc_control_header = mem; |
435 | UVC_COPY_DESCRIPTORS(mem, dst, | 546 | UVC_COPY_DESCRIPTORS(mem, dst, |
436 | (const struct usb_descriptor_header**)uvc->desc.control); | 547 | (const struct usb_descriptor_header **)uvc_control_desc); |
437 | uvc_control_header->wTotalLength = cpu_to_le16(control_size); | 548 | uvc_control_header->wTotalLength = cpu_to_le16(control_size); |
438 | uvc_control_header->bInCollection = 1; | 549 | uvc_control_header->bInCollection = 1; |
439 | uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf; | 550 | uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf; |
440 | 551 | ||
441 | UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_ep); | 552 | UVC_COPY_DESCRIPTOR(mem, dst, uvc_control_ep); |
553 | if (speed == USB_SPEED_SUPER) | ||
554 | UVC_COPY_DESCRIPTOR(mem, dst, &uvc_ss_control_comp); | ||
555 | |||
442 | UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_cs_ep); | 556 | UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_cs_ep); |
443 | UVC_COPY_DESCRIPTOR(mem, dst, &uvc_streaming_intf_alt0); | 557 | UVC_COPY_DESCRIPTOR(mem, dst, &uvc_streaming_intf_alt0); |
444 | 558 | ||
@@ -446,7 +560,8 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed) | |||
446 | UVC_COPY_DESCRIPTORS(mem, dst, | 560 | UVC_COPY_DESCRIPTORS(mem, dst, |
447 | (const struct usb_descriptor_header**)uvc_streaming_cls); | 561 | (const struct usb_descriptor_header**)uvc_streaming_cls); |
448 | uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size); | 562 | uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size); |
449 | uvc_streaming_header->bEndpointAddress = uvc_streaming_ep.bEndpointAddress; | 563 | uvc_streaming_header->bEndpointAddress = |
564 | uvc_fs_streaming_ep.bEndpointAddress; | ||
450 | 565 | ||
451 | UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std); | 566 | UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std); |
452 | 567 | ||
@@ -482,6 +597,7 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f) | |||
482 | 597 | ||
483 | kfree(f->descriptors); | 598 | kfree(f->descriptors); |
484 | kfree(f->hs_descriptors); | 599 | kfree(f->hs_descriptors); |
600 | kfree(f->ss_descriptors); | ||
485 | 601 | ||
486 | kfree(uvc); | 602 | kfree(uvc); |
487 | } | 603 | } |
@@ -496,8 +612,26 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) | |||
496 | 612 | ||
497 | INFO(cdev, "uvc_function_bind\n"); | 613 | INFO(cdev, "uvc_function_bind\n"); |
498 | 614 | ||
615 | /* sanity check the streaming endpoint module parameters */ | ||
616 | if (streaming_interval < 1) | ||
617 | streaming_interval = 1; | ||
618 | if (streaming_interval > 16) | ||
619 | streaming_interval = 16; | ||
620 | if (streaming_mult > 2) | ||
621 | streaming_mult = 2; | ||
622 | if (streaming_maxburst > 15) | ||
623 | streaming_maxburst = 15; | ||
624 | |||
625 | /* | ||
626 | * fill in the FS video streaming specific descriptors from the | ||
627 | * module parameters | ||
628 | */ | ||
629 | uvc_fs_streaming_ep.wMaxPacketSize = streaming_maxpacket > 1023 ? | ||
630 | 1023 : streaming_maxpacket; | ||
631 | uvc_fs_streaming_ep.bInterval = streaming_interval; | ||
632 | |||
499 | /* Allocate endpoints. */ | 633 | /* Allocate endpoints. */ |
500 | ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); | 634 | ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_control_ep); |
501 | if (!ep) { | 635 | if (!ep) { |
502 | INFO(cdev, "Unable to allocate control EP\n"); | 636 | INFO(cdev, "Unable to allocate control EP\n"); |
503 | goto error; | 637 | goto error; |
@@ -505,7 +639,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) | |||
505 | uvc->control_ep = ep; | 639 | uvc->control_ep = ep; |
506 | ep->driver_data = uvc; | 640 | ep->driver_data = uvc; |
507 | 641 | ||
508 | ep = usb_ep_autoconfig(cdev->gadget, &uvc_streaming_ep); | 642 | ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep); |
509 | if (!ep) { | 643 | if (!ep) { |
510 | INFO(cdev, "Unable to allocate streaming EP\n"); | 644 | INFO(cdev, "Unable to allocate streaming EP\n"); |
511 | goto error; | 645 | goto error; |
@@ -526,9 +660,52 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) | |||
526 | uvc_streaming_intf_alt1.bInterfaceNumber = ret; | 660 | uvc_streaming_intf_alt1.bInterfaceNumber = ret; |
527 | uvc->streaming_intf = ret; | 661 | uvc->streaming_intf = ret; |
528 | 662 | ||
529 | /* Copy descriptors. */ | 663 | /* sanity check the streaming endpoint module parameters */ |
664 | if (streaming_maxpacket > 1024) | ||
665 | streaming_maxpacket = 1024; | ||
666 | |||
667 | /* Copy descriptors for FS. */ | ||
530 | f->descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); | 668 | f->descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); |
531 | f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH); | 669 | |
670 | /* support high speed hardware */ | ||
671 | if (gadget_is_dualspeed(cdev->gadget)) { | ||
672 | /* | ||
673 | * Fill in the HS descriptors from the module parameters for the | ||
674 | * Video Streaming endpoint. | ||
675 | * NOTE: We assume that the user knows what they are doing and | ||
676 | * won't give parameters that their UDC doesn't support. | ||
677 | */ | ||
678 | uvc_hs_streaming_ep.wMaxPacketSize = streaming_maxpacket; | ||
679 | uvc_hs_streaming_ep.wMaxPacketSize |= streaming_mult << 11; | ||
680 | uvc_hs_streaming_ep.bInterval = streaming_interval; | ||
681 | uvc_hs_streaming_ep.bEndpointAddress = | ||
682 | uvc_fs_streaming_ep.bEndpointAddress; | ||
683 | |||
684 | /* Copy descriptors. */ | ||
685 | f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH); | ||
686 | } | ||
687 | |||
688 | /* support super speed hardware */ | ||
689 | if (gadget_is_superspeed(c->cdev->gadget)) { | ||
690 | /* | ||
691 | * Fill in the SS descriptors from the module parameters for the | ||
692 | * Video Streaming endpoint. | ||
693 | * NOTE: We assume that the user knows what they are doing and | ||
694 | * won't give parameters that their UDC doesn't support. | ||
695 | */ | ||
696 | uvc_ss_streaming_ep.wMaxPacketSize = streaming_maxpacket; | ||
697 | uvc_ss_streaming_ep.bInterval = streaming_interval; | ||
698 | uvc_ss_streaming_comp.bmAttributes = streaming_mult; | ||
699 | uvc_ss_streaming_comp.bMaxBurst = streaming_maxburst; | ||
700 | uvc_ss_streaming_comp.wBytesPerInterval = | ||
701 | streaming_maxpacket * (streaming_mult + 1) * | ||
702 | (streaming_maxburst + 1); | ||
703 | uvc_ss_streaming_ep.bEndpointAddress = | ||
704 | uvc_fs_streaming_ep.bEndpointAddress; | ||
705 | |||
706 | /* Copy descriptors. */ | ||
707 | f->ss_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_SUPER); | ||
708 | } | ||
532 | 709 | ||
533 | /* Preallocate control endpoint request. */ | 710 | /* Preallocate control endpoint request. */ |
534 | uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL); | 711 | uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL); |
@@ -583,9 +760,11 @@ error: | |||
583 | */ | 760 | */ |
584 | int __init | 761 | int __init |
585 | uvc_bind_config(struct usb_configuration *c, | 762 | uvc_bind_config(struct usb_configuration *c, |
586 | const struct uvc_descriptor_header * const *control, | 763 | const struct uvc_descriptor_header * const *fs_control, |
764 | const struct uvc_descriptor_header * const *ss_control, | ||
587 | const struct uvc_descriptor_header * const *fs_streaming, | 765 | const struct uvc_descriptor_header * const *fs_streaming, |
588 | const struct uvc_descriptor_header * const *hs_streaming) | 766 | const struct uvc_descriptor_header * const *hs_streaming, |
767 | const struct uvc_descriptor_header * const *ss_streaming) | ||
589 | { | 768 | { |
590 | struct uvc_device *uvc; | 769 | struct uvc_device *uvc; |
591 | int ret = 0; | 770 | int ret = 0; |
@@ -603,38 +782,54 @@ uvc_bind_config(struct usb_configuration *c, | |||
603 | uvc->state = UVC_STATE_DISCONNECTED; | 782 | uvc->state = UVC_STATE_DISCONNECTED; |
604 | 783 | ||
605 | /* Validate the descriptors. */ | 784 | /* Validate the descriptors. */ |
606 | if (control == NULL || control[0] == NULL || | 785 | if (fs_control == NULL || fs_control[0] == NULL || |
607 | control[0]->bDescriptorSubType != UVC_VC_HEADER) | 786 | fs_control[0]->bDescriptorSubType != UVC_VC_HEADER) |
608 | goto error; | 787 | goto error; |
609 | 788 | ||
610 | if (fs_streaming == NULL || fs_streaming[0] == NULL || | 789 | if (ss_control == NULL || ss_control[0] == NULL || |
611 | fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) | 790 | ss_control[0]->bDescriptorSubType != UVC_VC_HEADER) |
612 | goto error; | 791 | goto error; |
613 | 792 | ||
614 | if (hs_streaming == NULL || hs_streaming[0] == NULL || | 793 | if (fs_streaming == NULL || fs_streaming[0] == NULL || |
615 | hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) | 794 | fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) |
616 | goto error; | 795 | goto error; |
617 | 796 | ||
618 | uvc->desc.control = control; | 797 | if (hs_streaming == NULL || hs_streaming[0] == NULL || |
619 | uvc->desc.fs_streaming = fs_streaming; | 798 | hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) |
620 | uvc->desc.hs_streaming = hs_streaming; | ||
621 | |||
622 | /* Allocate string descriptor numbers. */ | ||
623 | if ((ret = usb_string_id(c->cdev)) < 0) | ||
624 | goto error; | 799 | goto error; |
625 | uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = ret; | ||
626 | uvc_iad.iFunction = ret; | ||
627 | 800 | ||
628 | if ((ret = usb_string_id(c->cdev)) < 0) | 801 | if (ss_streaming == NULL || ss_streaming[0] == NULL || |
802 | ss_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) | ||
629 | goto error; | 803 | goto error; |
630 | uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = ret; | ||
631 | uvc_control_intf.iInterface = ret; | ||
632 | 804 | ||
633 | if ((ret = usb_string_id(c->cdev)) < 0) | 805 | uvc->desc.fs_control = fs_control; |
634 | goto error; | 806 | uvc->desc.ss_control = ss_control; |
635 | uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id = ret; | 807 | uvc->desc.fs_streaming = fs_streaming; |
636 | uvc_streaming_intf_alt0.iInterface = ret; | 808 | uvc->desc.hs_streaming = hs_streaming; |
637 | uvc_streaming_intf_alt1.iInterface = ret; | 809 | uvc->desc.ss_streaming = ss_streaming; |
810 | |||
811 | /* maybe allocate device-global string IDs, and patch descriptors */ | ||
812 | if (uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id == 0) { | ||
813 | /* Allocate string descriptor numbers. */ | ||
814 | ret = usb_string_id(c->cdev); | ||
815 | if (ret < 0) | ||
816 | goto error; | ||
817 | uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = ret; | ||
818 | uvc_iad.iFunction = ret; | ||
819 | |||
820 | ret = usb_string_id(c->cdev); | ||
821 | if (ret < 0) | ||
822 | goto error; | ||
823 | uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = ret; | ||
824 | uvc_control_intf.iInterface = ret; | ||
825 | |||
826 | ret = usb_string_id(c->cdev); | ||
827 | if (ret < 0) | ||
828 | goto error; | ||
829 | uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id = ret; | ||
830 | uvc_streaming_intf_alt0.iInterface = ret; | ||
831 | uvc_streaming_intf_alt1.iInterface = ret; | ||
832 | } | ||
638 | 833 | ||
639 | /* Register the function. */ | 834 | /* Register the function. */ |
640 | uvc->func.name = "uvc"; | 835 | uvc->func.name = "uvc"; |
diff --git a/drivers/usb/gadget/f_uvc.h b/drivers/usb/gadget/f_uvc.h index abf832935134..c3d258d30188 100644 --- a/drivers/usb/gadget/f_uvc.h +++ b/drivers/usb/gadget/f_uvc.h | |||
@@ -17,9 +17,11 @@ | |||
17 | #include <linux/usb/video.h> | 17 | #include <linux/usb/video.h> |
18 | 18 | ||
19 | extern int uvc_bind_config(struct usb_configuration *c, | 19 | extern int uvc_bind_config(struct usb_configuration *c, |
20 | const struct uvc_descriptor_header * const *control, | 20 | const struct uvc_descriptor_header * const *fs_control, |
21 | const struct uvc_descriptor_header * const *fs_streaming, | 21 | const struct uvc_descriptor_header * const *hs_control, |
22 | const struct uvc_descriptor_header * const *hs_streaming); | 22 | const struct uvc_descriptor_header * const *fs_streaming, |
23 | const struct uvc_descriptor_header * const *hs_streaming, | ||
24 | const struct uvc_descriptor_header * const *ss_streaming); | ||
23 | 25 | ||
24 | #endif /* _F_UVC_H_ */ | 26 | #endif /* _F_UVC_H_ */ |
25 | 27 | ||
diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c index dcbc0a2e48dd..1b0f086426bd 100644 --- a/drivers/usb/gadget/fsl_mxc_udc.c +++ b/drivers/usb/gadget/fsl_mxc_udc.c | |||
@@ -21,7 +21,8 @@ | |||
21 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
22 | 22 | ||
23 | static struct clk *mxc_ahb_clk; | 23 | static struct clk *mxc_ahb_clk; |
24 | static struct clk *mxc_usb_clk; | 24 | static struct clk *mxc_per_clk; |
25 | static struct clk *mxc_ipg_clk; | ||
25 | 26 | ||
26 | /* workaround ENGcm09152 for i.MX35 */ | 27 | /* workaround ENGcm09152 for i.MX35 */ |
27 | #define USBPHYCTRL_OTGBASE_OFFSET 0x608 | 28 | #define USBPHYCTRL_OTGBASE_OFFSET 0x608 |
@@ -35,28 +36,31 @@ int fsl_udc_clk_init(struct platform_device *pdev) | |||
35 | 36 | ||
36 | pdata = pdev->dev.platform_data; | 37 | pdata = pdev->dev.platform_data; |
37 | 38 | ||
38 | if (!cpu_is_mx35() && !cpu_is_mx25()) { | 39 | mxc_ipg_clk = devm_clk_get(&pdev->dev, "ipg"); |
39 | mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb"); | 40 | if (IS_ERR(mxc_ipg_clk)) { |
40 | if (IS_ERR(mxc_ahb_clk)) | 41 | dev_err(&pdev->dev, "clk_get(\"ipg\") failed\n"); |
41 | return PTR_ERR(mxc_ahb_clk); | 42 | return PTR_ERR(mxc_ipg_clk); |
43 | } | ||
42 | 44 | ||
43 | ret = clk_enable(mxc_ahb_clk); | 45 | mxc_ahb_clk = devm_clk_get(&pdev->dev, "ahb"); |
44 | if (ret < 0) { | 46 | if (IS_ERR(mxc_ahb_clk)) { |
45 | dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n"); | 47 | dev_err(&pdev->dev, "clk_get(\"ahb\") failed\n"); |
46 | goto eenahb; | 48 | return PTR_ERR(mxc_ahb_clk); |
47 | } | ||
48 | } | 49 | } |
49 | 50 | ||
50 | /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ | 51 | mxc_per_clk = devm_clk_get(&pdev->dev, "per"); |
51 | mxc_usb_clk = clk_get(&pdev->dev, "usb"); | 52 | if (IS_ERR(mxc_per_clk)) { |
52 | if (IS_ERR(mxc_usb_clk)) { | 53 | dev_err(&pdev->dev, "clk_get(\"per\") failed\n"); |
53 | dev_err(&pdev->dev, "clk_get(\"usb\") failed\n"); | 54 | return PTR_ERR(mxc_per_clk); |
54 | ret = PTR_ERR(mxc_usb_clk); | ||
55 | goto egusb; | ||
56 | } | 55 | } |
57 | 56 | ||
57 | clk_prepare_enable(mxc_ipg_clk); | ||
58 | clk_prepare_enable(mxc_ahb_clk); | ||
59 | clk_prepare_enable(mxc_per_clk); | ||
60 | |||
61 | /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ | ||
58 | if (!cpu_is_mx51()) { | 62 | if (!cpu_is_mx51()) { |
59 | freq = clk_get_rate(mxc_usb_clk); | 63 | freq = clk_get_rate(mxc_per_clk); |
60 | if (pdata->phy_mode != FSL_USB2_PHY_ULPI && | 64 | if (pdata->phy_mode != FSL_USB2_PHY_ULPI && |
61 | (freq < 59999000 || freq > 60001000)) { | 65 | (freq < 59999000 || freq > 60001000)) { |
62 | dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq); | 66 | dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq); |
@@ -65,24 +69,13 @@ int fsl_udc_clk_init(struct platform_device *pdev) | |||
65 | } | 69 | } |
66 | } | 70 | } |
67 | 71 | ||
68 | ret = clk_enable(mxc_usb_clk); | ||
69 | if (ret < 0) { | ||
70 | dev_err(&pdev->dev, "clk_enable(\"usb_clk\") failed\n"); | ||
71 | goto eenusb; | ||
72 | } | ||
73 | |||
74 | return 0; | 72 | return 0; |
75 | 73 | ||
76 | eenusb: | ||
77 | eclkrate: | 74 | eclkrate: |
78 | clk_put(mxc_usb_clk); | 75 | clk_disable_unprepare(mxc_ipg_clk); |
79 | mxc_usb_clk = NULL; | 76 | clk_disable_unprepare(mxc_ahb_clk); |
80 | egusb: | 77 | clk_disable_unprepare(mxc_per_clk); |
81 | if (!cpu_is_mx35()) | 78 | mxc_per_clk = NULL; |
82 | clk_disable(mxc_ahb_clk); | ||
83 | eenahb: | ||
84 | if (!cpu_is_mx35()) | ||
85 | clk_put(mxc_ahb_clk); | ||
86 | return ret; | 79 | return ret; |
87 | } | 80 | } |
88 | 81 | ||
@@ -104,20 +97,15 @@ void fsl_udc_clk_finalize(struct platform_device *pdev) | |||
104 | 97 | ||
105 | /* ULPI transceivers don't need usbpll */ | 98 | /* ULPI transceivers don't need usbpll */ |
106 | if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { | 99 | if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { |
107 | clk_disable(mxc_usb_clk); | 100 | clk_disable_unprepare(mxc_per_clk); |
108 | clk_put(mxc_usb_clk); | 101 | mxc_per_clk = NULL; |
109 | mxc_usb_clk = NULL; | ||
110 | } | 102 | } |
111 | } | 103 | } |
112 | 104 | ||
113 | void fsl_udc_clk_release(void) | 105 | void fsl_udc_clk_release(void) |
114 | { | 106 | { |
115 | if (mxc_usb_clk) { | 107 | if (mxc_per_clk) |
116 | clk_disable(mxc_usb_clk); | 108 | clk_disable_unprepare(mxc_per_clk); |
117 | clk_put(mxc_usb_clk); | 109 | clk_disable_unprepare(mxc_ahb_clk); |
118 | } | 110 | clk_disable_unprepare(mxc_ipg_clk); |
119 | if (!cpu_is_mx35()) { | ||
120 | clk_disable(mxc_ahb_clk); | ||
121 | clk_put(mxc_ahb_clk); | ||
122 | } | ||
123 | } | 111 | } |
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index bc6f9bb9994a..a65ca0f5d8c4 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
@@ -2560,6 +2560,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2560 | dev_set_name(&udc_controller->gadget.dev, "gadget"); | 2560 | dev_set_name(&udc_controller->gadget.dev, "gadget"); |
2561 | udc_controller->gadget.dev.release = fsl_udc_release; | 2561 | udc_controller->gadget.dev.release = fsl_udc_release; |
2562 | udc_controller->gadget.dev.parent = &pdev->dev; | 2562 | udc_controller->gadget.dev.parent = &pdev->dev; |
2563 | udc_controller->gadget.dev.of_node = pdev->dev.of_node; | ||
2563 | ret = device_register(&udc_controller->gadget.dev); | 2564 | ret = device_register(&udc_controller->gadget.dev); |
2564 | if (ret < 0) | 2565 | if (ret < 0) |
2565 | goto err_free_irq; | 2566 | goto err_free_irq; |
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 54034f84f992..dc5334856afe 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c | |||
@@ -1432,7 +1432,7 @@ static int __init imx_udc_probe(struct platform_device *pdev) | |||
1432 | dev_err(&pdev->dev, "can't get USB clock\n"); | 1432 | dev_err(&pdev->dev, "can't get USB clock\n"); |
1433 | goto fail2; | 1433 | goto fail2; |
1434 | } | 1434 | } |
1435 | clk_enable(clk); | 1435 | clk_prepare_enable(clk); |
1436 | 1436 | ||
1437 | if (clk_get_rate(clk) != 48000000) { | 1437 | if (clk_get_rate(clk) != 48000000) { |
1438 | D_INI(&pdev->dev, | 1438 | D_INI(&pdev->dev, |
@@ -1496,7 +1496,7 @@ fail4: | |||
1496 | free_irq(imx_usb->usbd_int[i], imx_usb); | 1496 | free_irq(imx_usb->usbd_int[i], imx_usb); |
1497 | fail3: | 1497 | fail3: |
1498 | clk_put(clk); | 1498 | clk_put(clk); |
1499 | clk_disable(clk); | 1499 | clk_disable_unprepare(clk); |
1500 | fail2: | 1500 | fail2: |
1501 | iounmap(base); | 1501 | iounmap(base); |
1502 | fail1: | 1502 | fail1: |
@@ -1521,7 +1521,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev) | |||
1521 | free_irq(imx_usb->usbd_int[i], imx_usb); | 1521 | free_irq(imx_usb->usbd_int[i], imx_usb); |
1522 | 1522 | ||
1523 | clk_put(imx_usb->clk); | 1523 | clk_put(imx_usb->clk); |
1524 | clk_disable(imx_usb->clk); | 1524 | clk_disable_unprepare(imx_usb->clk); |
1525 | iounmap(imx_usb->base); | 1525 | iounmap(imx_usb->base); |
1526 | 1526 | ||
1527 | release_mem_region(imx_usb->res->start, resource_size(imx_usb->res)); | 1527 | release_mem_region(imx_usb->res->start, resource_size(imx_usb->res)); |
diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 2ab0388d93eb..f1ec99e69cb7 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c | |||
@@ -165,6 +165,7 @@ struct lpc32xx_udc { | |||
165 | int udp_irq[4]; | 165 | int udp_irq[4]; |
166 | struct clk *usb_pll_clk; | 166 | struct clk *usb_pll_clk; |
167 | struct clk *usb_slv_clk; | 167 | struct clk *usb_slv_clk; |
168 | struct clk *usb_otg_clk; | ||
168 | 169 | ||
169 | /* DMA support */ | 170 | /* DMA support */ |
170 | u32 *udca_v_base; | 171 | u32 *udca_v_base; |
@@ -227,33 +228,15 @@ static inline struct lpc32xx_udc *to_udc(struct usb_gadget *g) | |||
227 | #define UDCA_BUFF_SIZE (128) | 228 | #define UDCA_BUFF_SIZE (128) |
228 | 229 | ||
229 | /* TODO: When the clock framework is introduced in LPC32xx, IO_ADDRESS will | 230 | /* TODO: When the clock framework is introduced in LPC32xx, IO_ADDRESS will |
230 | * be replaced with an inremap()ed pointer, see USB_OTG_CLK_CTRL() | 231 | * be replaced with an inremap()ed pointer |
231 | * */ | 232 | * */ |
232 | #define USB_CTRL IO_ADDRESS(LPC32XX_CLK_PM_BASE + 0x64) | 233 | #define USB_CTRL IO_ADDRESS(LPC32XX_CLK_PM_BASE + 0x64) |
233 | #define USB_CLOCK_MASK (AHB_M_CLOCK_ON | OTG_CLOCK_ON | \ | ||
234 | DEV_CLOCK_ON | I2C_CLOCK_ON) | ||
235 | 234 | ||
236 | /* USB_CTRL bit defines */ | 235 | /* USB_CTRL bit defines */ |
237 | #define USB_SLAVE_HCLK_EN (1 << 24) | 236 | #define USB_SLAVE_HCLK_EN (1 << 24) |
238 | #define USB_HOST_NEED_CLK_EN (1 << 21) | 237 | #define USB_HOST_NEED_CLK_EN (1 << 21) |
239 | #define USB_DEV_NEED_CLK_EN (1 << 22) | 238 | #define USB_DEV_NEED_CLK_EN (1 << 22) |
240 | 239 | ||
241 | #define USB_OTG_CLK_CTRL(udc) ((udc)->udp_baseaddr + 0xFF4) | ||
242 | #define USB_OTG_CLK_STAT(udc) ((udc)->udp_baseaddr + 0xFF8) | ||
243 | |||
244 | /* USB_OTG_CLK_CTRL bit defines */ | ||
245 | #define AHB_M_CLOCK_ON (1 << 4) | ||
246 | #define OTG_CLOCK_ON (1 << 3) | ||
247 | #define I2C_CLOCK_ON (1 << 2) | ||
248 | #define DEV_CLOCK_ON (1 << 1) | ||
249 | #define HOST_CLOCK_ON (1 << 0) | ||
250 | |||
251 | #define USB_OTG_STAT_CONTROL(udc) (udc->udp_baseaddr + 0x110) | ||
252 | |||
253 | /* USB_OTG_STAT_CONTROL bit defines */ | ||
254 | #define TRANSPARENT_I2C_EN (1 << 7) | ||
255 | #define HOST_EN (1 << 0) | ||
256 | |||
257 | /********************************************************************** | 240 | /********************************************************************** |
258 | * USB device controller register offsets | 241 | * USB device controller register offsets |
259 | **********************************************************************/ | 242 | **********************************************************************/ |
@@ -677,7 +660,7 @@ static void isp1301_udc_configure(struct lpc32xx_udc *udc) | |||
677 | ISP1301_I2C_INTERRUPT_RISING, INT_VBUS_VLD); | 660 | ISP1301_I2C_INTERRUPT_RISING, INT_VBUS_VLD); |
678 | 661 | ||
679 | /* Enable usb_need_clk clock after transceiver is initialized */ | 662 | /* Enable usb_need_clk clock after transceiver is initialized */ |
680 | writel((readl(USB_CTRL) | (1 << 22)), USB_CTRL); | 663 | writel((readl(USB_CTRL) | USB_DEV_NEED_CLK_EN), USB_CTRL); |
681 | 664 | ||
682 | dev_info(udc->dev, "ISP1301 Vendor ID : 0x%04x\n", | 665 | dev_info(udc->dev, "ISP1301 Vendor ID : 0x%04x\n", |
683 | i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00)); | 666 | i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00)); |
@@ -1010,11 +993,8 @@ static void udc_dd_free(struct lpc32xx_udc *udc, struct lpc32xx_usbd_dd_gad *dd) | |||
1010 | /* Enables or disables most of the USB system clocks when low power mode is | 993 | /* Enables or disables most of the USB system clocks when low power mode is |
1011 | * needed. Clocks are typically started on a connection event, and disabled | 994 | * needed. Clocks are typically started on a connection event, and disabled |
1012 | * when a cable is disconnected */ | 995 | * when a cable is disconnected */ |
1013 | #define OTGOFF_CLK_MASK (AHB_M_CLOCK_ON | I2C_CLOCK_ON) | ||
1014 | static void udc_clk_set(struct lpc32xx_udc *udc, int enable) | 996 | static void udc_clk_set(struct lpc32xx_udc *udc, int enable) |
1015 | { | 997 | { |
1016 | int to = 1000; | ||
1017 | |||
1018 | if (enable != 0) { | 998 | if (enable != 0) { |
1019 | if (udc->clocked) | 999 | if (udc->clocked) |
1020 | return; | 1000 | return; |
@@ -1028,14 +1008,7 @@ static void udc_clk_set(struct lpc32xx_udc *udc, int enable) | |||
1028 | writel(readl(USB_CTRL) | USB_DEV_NEED_CLK_EN, | 1008 | writel(readl(USB_CTRL) | USB_DEV_NEED_CLK_EN, |
1029 | USB_CTRL); | 1009 | USB_CTRL); |
1030 | 1010 | ||
1031 | /* Set to enable all needed USB OTG clocks */ | 1011 | clk_enable(udc->usb_otg_clk); |
1032 | writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL(udc)); | ||
1033 | |||
1034 | while (((readl(USB_OTG_CLK_STAT(udc)) & USB_CLOCK_MASK) != | ||
1035 | USB_CLOCK_MASK) && (to > 0)) | ||
1036 | to--; | ||
1037 | if (!to) | ||
1038 | dev_dbg(udc->dev, "Cannot enable USB OTG clocking\n"); | ||
1039 | } else { | 1012 | } else { |
1040 | if (!udc->clocked) | 1013 | if (!udc->clocked) |
1041 | return; | 1014 | return; |
@@ -1047,19 +1020,11 @@ static void udc_clk_set(struct lpc32xx_udc *udc, int enable) | |||
1047 | /* 48MHz PLL dpwn */ | 1020 | /* 48MHz PLL dpwn */ |
1048 | clk_disable(udc->usb_pll_clk); | 1021 | clk_disable(udc->usb_pll_clk); |
1049 | 1022 | ||
1050 | /* Enable the USB device clock */ | 1023 | /* Disable the USB device clock */ |
1051 | writel(readl(USB_CTRL) & ~USB_DEV_NEED_CLK_EN, | 1024 | writel(readl(USB_CTRL) & ~USB_DEV_NEED_CLK_EN, |
1052 | USB_CTRL); | 1025 | USB_CTRL); |
1053 | 1026 | ||
1054 | /* Set to enable all needed USB OTG clocks */ | 1027 | clk_disable(udc->usb_otg_clk); |
1055 | writel(OTGOFF_CLK_MASK, USB_OTG_CLK_CTRL(udc)); | ||
1056 | |||
1057 | while (((readl(USB_OTG_CLK_STAT(udc)) & | ||
1058 | OTGOFF_CLK_MASK) != | ||
1059 | OTGOFF_CLK_MASK) && (to > 0)) | ||
1060 | to--; | ||
1061 | if (!to) | ||
1062 | dev_dbg(udc->dev, "Cannot disable USB OTG clocking\n"); | ||
1063 | } | 1028 | } |
1064 | } | 1029 | } |
1065 | 1030 | ||
@@ -3041,6 +3006,7 @@ static int lpc32xx_start(struct usb_gadget_driver *driver, | |||
3041 | 3006 | ||
3042 | udc->driver = driver; | 3007 | udc->driver = driver; |
3043 | udc->gadget.dev.driver = &driver->driver; | 3008 | udc->gadget.dev.driver = &driver->driver; |
3009 | udc->gadget.dev.of_node = udc->dev->of_node; | ||
3044 | udc->enabled = 1; | 3010 | udc->enabled = 1; |
3045 | udc->selfpowered = 1; | 3011 | udc->selfpowered = 1; |
3046 | udc->vbus = 0; | 3012 | udc->vbus = 0; |
@@ -3239,6 +3205,12 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) | |||
3239 | retval = PTR_ERR(udc->usb_slv_clk); | 3205 | retval = PTR_ERR(udc->usb_slv_clk); |
3240 | goto usb_clk_get_fail; | 3206 | goto usb_clk_get_fail; |
3241 | } | 3207 | } |
3208 | udc->usb_otg_clk = clk_get(&pdev->dev, "ck_usb_otg"); | ||
3209 | if (IS_ERR(udc->usb_otg_clk)) { | ||
3210 | dev_err(udc->dev, "failed to acquire USB otg clock\n"); | ||
3211 | retval = PTR_ERR(udc->usb_slv_clk); | ||
3212 | goto usb_otg_clk_get_fail; | ||
3213 | } | ||
3242 | 3214 | ||
3243 | /* Setup PLL clock to 48MHz */ | 3215 | /* Setup PLL clock to 48MHz */ |
3244 | retval = clk_enable(udc->usb_pll_clk); | 3216 | retval = clk_enable(udc->usb_pll_clk); |
@@ -3262,15 +3234,12 @@ static int __init lpc32xx_udc_probe(struct platform_device *pdev) | |||
3262 | goto usb_clk_enable_fail; | 3234 | goto usb_clk_enable_fail; |
3263 | } | 3235 | } |
3264 | 3236 | ||
3265 | /* Set to enable all needed USB OTG clocks */ | 3237 | /* Enable USB OTG clock */ |
3266 | writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL(udc)); | 3238 | retval = clk_enable(udc->usb_otg_clk); |
3267 | 3239 | if (retval < 0) { | |
3268 | i = 1000; | 3240 | dev_err(udc->dev, "failed to start USB otg clock\n"); |
3269 | while (((readl(USB_OTG_CLK_STAT(udc)) & USB_CLOCK_MASK) != | 3241 | goto usb_otg_clk_enable_fail; |
3270 | USB_CLOCK_MASK) && (i > 0)) | 3242 | } |
3271 | i--; | ||
3272 | if (!i) | ||
3273 | dev_dbg(udc->dev, "USB OTG clocks not correctly enabled\n"); | ||
3274 | 3243 | ||
3275 | /* Setup deferred workqueue data */ | 3244 | /* Setup deferred workqueue data */ |
3276 | udc->poweron = udc->pullup = 0; | 3245 | udc->poweron = udc->pullup = 0; |
@@ -3390,12 +3359,16 @@ dma_alloc_fail: | |||
3390 | dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, | 3359 | dma_free_coherent(&pdev->dev, UDCA_BUFF_SIZE, |
3391 | udc->udca_v_base, udc->udca_p_base); | 3360 | udc->udca_v_base, udc->udca_p_base); |
3392 | i2c_fail: | 3361 | i2c_fail: |
3362 | clk_disable(udc->usb_otg_clk); | ||
3363 | usb_otg_clk_enable_fail: | ||
3393 | clk_disable(udc->usb_slv_clk); | 3364 | clk_disable(udc->usb_slv_clk); |
3394 | usb_clk_enable_fail: | 3365 | usb_clk_enable_fail: |
3395 | pll_set_fail: | 3366 | pll_set_fail: |
3396 | clk_disable(udc->usb_pll_clk); | 3367 | clk_disable(udc->usb_pll_clk); |
3397 | pll_enable_fail: | 3368 | pll_enable_fail: |
3398 | clk_put(udc->usb_slv_clk); | 3369 | clk_put(udc->usb_slv_clk); |
3370 | usb_otg_clk_get_fail: | ||
3371 | clk_put(udc->usb_otg_clk); | ||
3399 | usb_clk_get_fail: | 3372 | usb_clk_get_fail: |
3400 | clk_put(udc->usb_pll_clk); | 3373 | clk_put(udc->usb_pll_clk); |
3401 | pll_get_fail: | 3374 | pll_get_fail: |
@@ -3433,6 +3406,8 @@ static int __devexit lpc32xx_udc_remove(struct platform_device *pdev) | |||
3433 | 3406 | ||
3434 | device_unregister(&udc->gadget.dev); | 3407 | device_unregister(&udc->gadget.dev); |
3435 | 3408 | ||
3409 | clk_disable(udc->usb_otg_clk); | ||
3410 | clk_put(udc->usb_otg_clk); | ||
3436 | clk_disable(udc->usb_slv_clk); | 3411 | clk_disable(udc->usb_slv_clk); |
3437 | clk_put(udc->usb_slv_clk); | 3412 | clk_put(udc->usb_slv_clk); |
3438 | clk_disable(udc->usb_pll_clk); | 3413 | clk_disable(udc->usb_pll_clk); |
@@ -3446,7 +3421,6 @@ static int __devexit lpc32xx_udc_remove(struct platform_device *pdev) | |||
3446 | #ifdef CONFIG_PM | 3421 | #ifdef CONFIG_PM |
3447 | static int lpc32xx_udc_suspend(struct platform_device *pdev, pm_message_t mesg) | 3422 | static int lpc32xx_udc_suspend(struct platform_device *pdev, pm_message_t mesg) |
3448 | { | 3423 | { |
3449 | int to = 1000; | ||
3450 | struct lpc32xx_udc *udc = platform_get_drvdata(pdev); | 3424 | struct lpc32xx_udc *udc = platform_get_drvdata(pdev); |
3451 | 3425 | ||
3452 | if (udc->clocked) { | 3426 | if (udc->clocked) { |
@@ -3461,15 +3435,6 @@ static int lpc32xx_udc_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
3461 | on resume */ | 3435 | on resume */ |
3462 | udc->clocked = 1; | 3436 | udc->clocked = 1; |
3463 | 3437 | ||
3464 | /* Kill OTG and I2C clocks */ | ||
3465 | writel(0, USB_OTG_CLK_CTRL(udc)); | ||
3466 | while (((readl(USB_OTG_CLK_STAT(udc)) & OTGOFF_CLK_MASK) != | ||
3467 | OTGOFF_CLK_MASK) && (to > 0)) | ||
3468 | to--; | ||
3469 | if (!to) | ||
3470 | dev_dbg(udc->dev, | ||
3471 | "USB OTG clocks not correctly enabled\n"); | ||
3472 | |||
3473 | /* Kill global USB clock */ | 3438 | /* Kill global USB clock */ |
3474 | clk_disable(udc->usb_slv_clk); | 3439 | clk_disable(udc->usb_slv_clk); |
3475 | } | 3440 | } |
diff --git a/drivers/usb/gadget/mv_u3d.h b/drivers/usb/gadget/mv_u3d.h new file mode 100644 index 000000000000..e32a787ac373 --- /dev/null +++ b/drivers/usb/gadget/mv_u3d.h | |||
@@ -0,0 +1,320 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Marvell International Ltd. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #ifndef __MV_U3D_H | ||
10 | #define __MV_U3D_H | ||
11 | |||
12 | #define MV_U3D_EP_CONTEXT_ALIGNMENT 32 | ||
13 | #define MV_U3D_TRB_ALIGNMENT 16 | ||
14 | #define MV_U3D_DMA_BOUNDARY 4096 | ||
15 | #define MV_U3D_EP0_MAX_PKT_SIZE 512 | ||
16 | |||
17 | /* ep0 transfer state */ | ||
18 | #define MV_U3D_WAIT_FOR_SETUP 0 | ||
19 | #define MV_U3D_DATA_STATE_XMIT 1 | ||
20 | #define MV_U3D_DATA_STATE_NEED_ZLP 2 | ||
21 | #define MV_U3D_WAIT_FOR_OUT_STATUS 3 | ||
22 | #define MV_U3D_DATA_STATE_RECV 4 | ||
23 | #define MV_U3D_STATUS_STAGE 5 | ||
24 | |||
25 | #define MV_U3D_EP_MAX_LENGTH_TRANSFER 0x10000 | ||
26 | |||
27 | /* USB3 Interrupt Status */ | ||
28 | #define MV_U3D_USBINT_SETUP 0x00000001 | ||
29 | #define MV_U3D_USBINT_RX_COMPLETE 0x00000002 | ||
30 | #define MV_U3D_USBINT_TX_COMPLETE 0x00000004 | ||
31 | #define MV_U3D_USBINT_UNDER_RUN 0x00000008 | ||
32 | #define MV_U3D_USBINT_RXDESC_ERR 0x00000010 | ||
33 | #define MV_U3D_USBINT_TXDESC_ERR 0x00000020 | ||
34 | #define MV_U3D_USBINT_RX_TRB_COMPLETE 0x00000040 | ||
35 | #define MV_U3D_USBINT_TX_TRB_COMPLETE 0x00000080 | ||
36 | #define MV_U3D_USBINT_VBUS_VALID 0x00010000 | ||
37 | #define MV_U3D_USBINT_STORAGE_CMD_FULL 0x00020000 | ||
38 | #define MV_U3D_USBINT_LINK_CHG 0x01000000 | ||
39 | |||
40 | /* USB3 Interrupt Enable */ | ||
41 | #define MV_U3D_INTR_ENABLE_SETUP 0x00000001 | ||
42 | #define MV_U3D_INTR_ENABLE_RX_COMPLETE 0x00000002 | ||
43 | #define MV_U3D_INTR_ENABLE_TX_COMPLETE 0x00000004 | ||
44 | #define MV_U3D_INTR_ENABLE_UNDER_RUN 0x00000008 | ||
45 | #define MV_U3D_INTR_ENABLE_RXDESC_ERR 0x00000010 | ||
46 | #define MV_U3D_INTR_ENABLE_TXDESC_ERR 0x00000020 | ||
47 | #define MV_U3D_INTR_ENABLE_RX_TRB_COMPLETE 0x00000040 | ||
48 | #define MV_U3D_INTR_ENABLE_TX_TRB_COMPLETE 0x00000080 | ||
49 | #define MV_U3D_INTR_ENABLE_RX_BUFFER_ERR 0x00000100 | ||
50 | #define MV_U3D_INTR_ENABLE_VBUS_VALID 0x00010000 | ||
51 | #define MV_U3D_INTR_ENABLE_STORAGE_CMD_FULL 0x00020000 | ||
52 | #define MV_U3D_INTR_ENABLE_LINK_CHG 0x01000000 | ||
53 | #define MV_U3D_INTR_ENABLE_PRIME_STATUS 0x02000000 | ||
54 | |||
55 | /* USB3 Link Change */ | ||
56 | #define MV_U3D_LINK_CHANGE_LINK_UP 0x00000001 | ||
57 | #define MV_U3D_LINK_CHANGE_SUSPEND 0x00000002 | ||
58 | #define MV_U3D_LINK_CHANGE_RESUME 0x00000004 | ||
59 | #define MV_U3D_LINK_CHANGE_WRESET 0x00000008 | ||
60 | #define MV_U3D_LINK_CHANGE_HRESET 0x00000010 | ||
61 | #define MV_U3D_LINK_CHANGE_VBUS_INVALID 0x00000020 | ||
62 | #define MV_U3D_LINK_CHANGE_INACT 0x00000040 | ||
63 | #define MV_U3D_LINK_CHANGE_DISABLE_AFTER_U0 0x00000080 | ||
64 | #define MV_U3D_LINK_CHANGE_U1 0x00000100 | ||
65 | #define MV_U3D_LINK_CHANGE_U2 0x00000200 | ||
66 | #define MV_U3D_LINK_CHANGE_U3 0x00000400 | ||
67 | |||
68 | /* bridge setting */ | ||
69 | #define MV_U3D_BRIDGE_SETTING_VBUS_VALID (1 << 16) | ||
70 | |||
71 | /* Command Register Bit Masks */ | ||
72 | #define MV_U3D_CMD_RUN_STOP 0x00000001 | ||
73 | #define MV_U3D_CMD_CTRL_RESET 0x00000002 | ||
74 | |||
75 | /* ep control register */ | ||
76 | #define MV_U3D_EPXCR_EP_TYPE_CONTROL 0 | ||
77 | #define MV_U3D_EPXCR_EP_TYPE_ISOC 1 | ||
78 | #define MV_U3D_EPXCR_EP_TYPE_BULK 2 | ||
79 | #define MV_U3D_EPXCR_EP_TYPE_INT 3 | ||
80 | #define MV_U3D_EPXCR_EP_ENABLE_SHIFT 4 | ||
81 | #define MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT 12 | ||
82 | #define MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT 16 | ||
83 | #define MV_U3D_USB_BULK_BURST_OUT 6 | ||
84 | #define MV_U3D_USB_BULK_BURST_IN 14 | ||
85 | |||
86 | #define MV_U3D_EPXCR_EP_FLUSH (1 << 7) | ||
87 | #define MV_U3D_EPXCR_EP_HALT (1 << 1) | ||
88 | #define MV_U3D_EPXCR_EP_INIT (1) | ||
89 | |||
90 | /* TX/RX Status Register */ | ||
91 | #define MV_U3D_XFERSTATUS_COMPLETE_SHIFT 24 | ||
92 | #define MV_U3D_COMPLETE_INVALID 0 | ||
93 | #define MV_U3D_COMPLETE_SUCCESS 1 | ||
94 | #define MV_U3D_COMPLETE_BUFF_ERR 2 | ||
95 | #define MV_U3D_COMPLETE_SHORT_PACKET 3 | ||
96 | #define MV_U3D_COMPLETE_TRB_ERR 5 | ||
97 | #define MV_U3D_XFERSTATUS_TRB_LENGTH_MASK (0xFFFFFF) | ||
98 | |||
99 | #define MV_U3D_USB_LINK_BYPASS_VBUS 0x8 | ||
100 | |||
101 | #define MV_U3D_LTSSM_PHY_INIT_DONE 0x80000000 | ||
102 | #define MV_U3D_LTSSM_NEVER_GO_COMPLIANCE 0x40000000 | ||
103 | |||
104 | #define MV_U3D_USB3_OP_REGS_OFFSET 0x100 | ||
105 | #define MV_U3D_USB3_PHY_OFFSET 0xB800 | ||
106 | |||
107 | #define DCS_ENABLE 0x1 | ||
108 | |||
109 | /* timeout */ | ||
110 | #define MV_U3D_RESET_TIMEOUT 10000 | ||
111 | #define MV_U3D_FLUSH_TIMEOUT 100000 | ||
112 | #define MV_U3D_OWN_TIMEOUT 10000 | ||
113 | #define LOOPS_USEC_SHIFT 4 | ||
114 | #define LOOPS_USEC (1 << LOOPS_USEC_SHIFT) | ||
115 | #define LOOPS(timeout) ((timeout) >> LOOPS_USEC_SHIFT) | ||
116 | |||
117 | /* ep direction */ | ||
118 | #define MV_U3D_EP_DIR_IN 1 | ||
119 | #define MV_U3D_EP_DIR_OUT 0 | ||
120 | #define mv_u3d_ep_dir(ep) (((ep)->ep_num == 0) ? \ | ||
121 | ((ep)->u3d->ep0_dir) : ((ep)->direction)) | ||
122 | |||
123 | /* usb capability registers */ | ||
124 | struct mv_u3d_cap_regs { | ||
125 | u32 rsvd[5]; | ||
126 | u32 dboff; /* doorbell register offset */ | ||
127 | u32 rtsoff; /* runtime register offset */ | ||
128 | u32 vuoff; /* vendor unique register offset */ | ||
129 | }; | ||
130 | |||
131 | /* operation registers */ | ||
132 | struct mv_u3d_op_regs { | ||
133 | u32 usbcmd; /* Command register */ | ||
134 | u32 rsvd1[11]; | ||
135 | u32 dcbaapl; /* Device Context Base Address low register */ | ||
136 | u32 dcbaaph; /* Device Context Base Address high register */ | ||
137 | u32 rsvd2[243]; | ||
138 | u32 portsc; /* port status and control register*/ | ||
139 | u32 portlinkinfo; /* port link info register*/ | ||
140 | u32 rsvd3[9917]; | ||
141 | u32 doorbell; /* doorbell register */ | ||
142 | }; | ||
143 | |||
144 | /* control enpoint enable registers */ | ||
145 | struct epxcr { | ||
146 | u32 epxoutcr0; /* ep out control 0 register */ | ||
147 | u32 epxoutcr1; /* ep out control 1 register */ | ||
148 | u32 epxincr0; /* ep in control 0 register */ | ||
149 | u32 epxincr1; /* ep in control 1 register */ | ||
150 | }; | ||
151 | |||
152 | /* transfer status registers */ | ||
153 | struct xferstatus { | ||
154 | u32 curdeqlo; /* current TRB pointer low */ | ||
155 | u32 curdeqhi; /* current TRB pointer high */ | ||
156 | u32 statuslo; /* transfer status low */ | ||
157 | u32 statushi; /* transfer status high */ | ||
158 | }; | ||
159 | |||
160 | /* vendor unique control registers */ | ||
161 | struct mv_u3d_vuc_regs { | ||
162 | u32 ctrlepenable; /* control endpoint enable register */ | ||
163 | u32 setuplock; /* setup lock register */ | ||
164 | u32 endcomplete; /* endpoint transfer complete register */ | ||
165 | u32 intrcause; /* interrupt cause register */ | ||
166 | u32 intrenable; /* interrupt enable register */ | ||
167 | u32 trbcomplete; /* TRB complete register */ | ||
168 | u32 linkchange; /* link change register */ | ||
169 | u32 rsvd1[5]; | ||
170 | u32 trbunderrun; /* TRB underrun register */ | ||
171 | u32 rsvd2[43]; | ||
172 | u32 bridgesetting; /* bridge setting register */ | ||
173 | u32 rsvd3[7]; | ||
174 | struct xferstatus txst[16]; /* TX status register */ | ||
175 | struct xferstatus rxst[16]; /* RX status register */ | ||
176 | u32 ltssm; /* LTSSM control register */ | ||
177 | u32 pipe; /* PIPE control register */ | ||
178 | u32 linkcr0; /* link control 0 register */ | ||
179 | u32 linkcr1; /* link control 1 register */ | ||
180 | u32 rsvd6[60]; | ||
181 | u32 mib0; /* MIB0 counter register */ | ||
182 | u32 usblink; /* usb link control register */ | ||
183 | u32 ltssmstate; /* LTSSM state register */ | ||
184 | u32 linkerrorcause; /* link error cause register */ | ||
185 | u32 rsvd7[60]; | ||
186 | u32 devaddrtiebrkr; /* device address and tie breaker */ | ||
187 | u32 itpinfo0; /* ITP info 0 register */ | ||
188 | u32 itpinfo1; /* ITP info 1 register */ | ||
189 | u32 rsvd8[61]; | ||
190 | struct epxcr epcr[16]; /* ep control register */ | ||
191 | u32 rsvd9[64]; | ||
192 | u32 phyaddr; /* PHY address register */ | ||
193 | u32 phydata; /* PHY data register */ | ||
194 | }; | ||
195 | |||
196 | /* Endpoint context structure */ | ||
197 | struct mv_u3d_ep_context { | ||
198 | u32 rsvd0; | ||
199 | u32 rsvd1; | ||
200 | u32 trb_addr_lo; /* TRB address low 32 bit */ | ||
201 | u32 trb_addr_hi; /* TRB address high 32 bit */ | ||
202 | u32 rsvd2; | ||
203 | u32 rsvd3; | ||
204 | struct usb_ctrlrequest setup_buffer; /* setup data buffer */ | ||
205 | }; | ||
206 | |||
207 | /* TRB control data structure */ | ||
208 | struct mv_u3d_trb_ctrl { | ||
209 | u32 own:1; /* owner of TRB */ | ||
210 | u32 rsvd1:3; | ||
211 | u32 chain:1; /* associate this TRB with the | ||
212 | next TRB on the Ring */ | ||
213 | u32 ioc:1; /* interrupt on complete */ | ||
214 | u32 rsvd2:4; | ||
215 | u32 type:6; /* TRB type */ | ||
216 | #define TYPE_NORMAL 1 | ||
217 | #define TYPE_DATA 3 | ||
218 | #define TYPE_LINK 6 | ||
219 | u32 dir:1; /* Working at data stage of control endpoint | ||
220 | operation. 0 is OUT and 1 is IN. */ | ||
221 | u32 rsvd3:15; | ||
222 | }; | ||
223 | |||
224 | /* TRB data structure | ||
225 | * For multiple TRB, all the TRBs' physical address should be continuous. | ||
226 | */ | ||
227 | struct mv_u3d_trb_hw { | ||
228 | u32 buf_addr_lo; /* data buffer address low 32 bit */ | ||
229 | u32 buf_addr_hi; /* data buffer address high 32 bit */ | ||
230 | u32 trb_len; /* transfer length */ | ||
231 | struct mv_u3d_trb_ctrl ctrl; /* TRB control data */ | ||
232 | }; | ||
233 | |||
234 | /* TRB structure */ | ||
235 | struct mv_u3d_trb { | ||
236 | struct mv_u3d_trb_hw *trb_hw; /* point to the trb_hw structure */ | ||
237 | dma_addr_t trb_dma; /* dma address for this trb_hw */ | ||
238 | struct list_head trb_list; /* trb list */ | ||
239 | }; | ||
240 | |||
241 | /* device data structure */ | ||
242 | struct mv_u3d { | ||
243 | struct usb_gadget gadget; | ||
244 | struct usb_gadget_driver *driver; | ||
245 | spinlock_t lock; /* device lock */ | ||
246 | struct completion *done; | ||
247 | struct device *dev; | ||
248 | int irq; | ||
249 | |||
250 | /* usb controller registers */ | ||
251 | struct mv_u3d_cap_regs __iomem *cap_regs; | ||
252 | struct mv_u3d_op_regs __iomem *op_regs; | ||
253 | struct mv_u3d_vuc_regs __iomem *vuc_regs; | ||
254 | void __iomem *phy_regs; | ||
255 | |||
256 | unsigned int max_eps; | ||
257 | struct mv_u3d_ep_context *ep_context; | ||
258 | size_t ep_context_size; | ||
259 | dma_addr_t ep_context_dma; | ||
260 | |||
261 | struct dma_pool *trb_pool; /* for TRB data structure */ | ||
262 | struct mv_u3d_ep *eps; | ||
263 | |||
264 | struct mv_u3d_req *status_req; /* ep0 status request */ | ||
265 | struct usb_ctrlrequest local_setup_buff; /* store setup data*/ | ||
266 | |||
267 | unsigned int resume_state; /* USB state to resume */ | ||
268 | unsigned int usb_state; /* USB current state */ | ||
269 | unsigned int ep0_state; /* Endpoint zero state */ | ||
270 | unsigned int ep0_dir; | ||
271 | |||
272 | unsigned int dev_addr; /* device address */ | ||
273 | |||
274 | unsigned int errors; | ||
275 | |||
276 | unsigned softconnect:1; | ||
277 | unsigned vbus_active:1; /* vbus is active or not */ | ||
278 | unsigned remote_wakeup:1; /* support remote wakeup */ | ||
279 | unsigned clock_gating:1; /* clock gating or not */ | ||
280 | unsigned active:1; /* udc is active or not */ | ||
281 | unsigned vbus_valid_detect:1; /* udc vbus detection */ | ||
282 | |||
283 | struct mv_usb_addon_irq *vbus; | ||
284 | unsigned int power; | ||
285 | |||
286 | struct clk *clk; | ||
287 | }; | ||
288 | |||
289 | /* endpoint data structure */ | ||
290 | struct mv_u3d_ep { | ||
291 | struct usb_ep ep; | ||
292 | struct mv_u3d *u3d; | ||
293 | struct list_head queue; /* ep request queued hardware */ | ||
294 | struct list_head req_list; /* list of ep request */ | ||
295 | struct mv_u3d_ep_context *ep_context; /* ep context */ | ||
296 | u32 direction; | ||
297 | char name[14]; | ||
298 | u32 processing; /* there is ep request | ||
299 | queued on haredware */ | ||
300 | spinlock_t req_lock; /* ep lock */ | ||
301 | unsigned wedge:1; | ||
302 | unsigned enabled:1; | ||
303 | unsigned ep_type:2; | ||
304 | unsigned ep_num:8; | ||
305 | }; | ||
306 | |||
307 | /* request data structure */ | ||
308 | struct mv_u3d_req { | ||
309 | struct usb_request req; | ||
310 | struct mv_u3d_ep *ep; | ||
311 | struct list_head queue; /* ep requst queued on hardware */ | ||
312 | struct list_head list; /* ep request list */ | ||
313 | struct list_head trb_list; /* trb list of a request */ | ||
314 | |||
315 | struct mv_u3d_trb *trb_head; /* point to first trb of a request */ | ||
316 | unsigned trb_count; /* TRB number in the chain */ | ||
317 | unsigned chain; /* TRB chain or not */ | ||
318 | }; | ||
319 | |||
320 | #endif | ||
diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c new file mode 100644 index 000000000000..8cfd5b028dbd --- /dev/null +++ b/drivers/usb/gadget/mv_u3d_core.c | |||
@@ -0,0 +1,2098 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Marvell International Ltd. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/dma-mapping.h> | ||
11 | #include <linux/dmapool.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/ioport.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/timer.h> | ||
20 | #include <linux/list.h> | ||
21 | #include <linux/notifier.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/moduleparam.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/usb/ch9.h> | ||
26 | #include <linux/usb/gadget.h> | ||
27 | #include <linux/pm.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <linux/irq.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/platform_data/mv_usb.h> | ||
32 | #include <linux/clk.h> | ||
33 | #include <asm/system.h> | ||
34 | #include <asm/unaligned.h> | ||
35 | #include <asm/byteorder.h> | ||
36 | |||
37 | #include "mv_u3d.h" | ||
38 | |||
39 | #define DRIVER_DESC "Marvell PXA USB3.0 Device Controller driver" | ||
40 | |||
41 | static const char driver_name[] = "mv_u3d"; | ||
42 | static const char driver_desc[] = DRIVER_DESC; | ||
43 | |||
44 | static void mv_u3d_nuke(struct mv_u3d_ep *ep, int status); | ||
45 | static void mv_u3d_stop_activity(struct mv_u3d *u3d, | ||
46 | struct usb_gadget_driver *driver); | ||
47 | |||
48 | /* for endpoint 0 operations */ | ||
49 | static const struct usb_endpoint_descriptor mv_u3d_ep0_desc = { | ||
50 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
51 | .bDescriptorType = USB_DT_ENDPOINT, | ||
52 | .bEndpointAddress = 0, | ||
53 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | ||
54 | .wMaxPacketSize = MV_U3D_EP0_MAX_PKT_SIZE, | ||
55 | }; | ||
56 | |||
57 | static void mv_u3d_ep0_reset(struct mv_u3d *u3d) | ||
58 | { | ||
59 | struct mv_u3d_ep *ep; | ||
60 | u32 epxcr; | ||
61 | int i; | ||
62 | |||
63 | for (i = 0; i < 2; i++) { | ||
64 | ep = &u3d->eps[i]; | ||
65 | ep->u3d = u3d; | ||
66 | |||
67 | /* ep0 ep context, ep0 in and out share the same ep context */ | ||
68 | ep->ep_context = &u3d->ep_context[1]; | ||
69 | } | ||
70 | |||
71 | /* reset ep state machine */ | ||
72 | /* reset ep0 out */ | ||
73 | epxcr = ioread32(&u3d->vuc_regs->epcr[0].epxoutcr0); | ||
74 | epxcr |= MV_U3D_EPXCR_EP_INIT; | ||
75 | iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxoutcr0); | ||
76 | udelay(5); | ||
77 | epxcr &= ~MV_U3D_EPXCR_EP_INIT; | ||
78 | iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxoutcr0); | ||
79 | |||
80 | epxcr = ((MV_U3D_EP0_MAX_PKT_SIZE | ||
81 | << MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT) | ||
82 | | (1 << MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT) | ||
83 | | (1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) | ||
84 | | MV_U3D_EPXCR_EP_TYPE_CONTROL); | ||
85 | iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxoutcr1); | ||
86 | |||
87 | /* reset ep0 in */ | ||
88 | epxcr = ioread32(&u3d->vuc_regs->epcr[0].epxincr0); | ||
89 | epxcr |= MV_U3D_EPXCR_EP_INIT; | ||
90 | iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxincr0); | ||
91 | udelay(5); | ||
92 | epxcr &= ~MV_U3D_EPXCR_EP_INIT; | ||
93 | iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxincr0); | ||
94 | |||
95 | epxcr = ((MV_U3D_EP0_MAX_PKT_SIZE | ||
96 | << MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT) | ||
97 | | (1 << MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT) | ||
98 | | (1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) | ||
99 | | MV_U3D_EPXCR_EP_TYPE_CONTROL); | ||
100 | iowrite32(epxcr, &u3d->vuc_regs->epcr[0].epxincr1); | ||
101 | } | ||
102 | |||
103 | static void mv_u3d_ep0_stall(struct mv_u3d *u3d) | ||
104 | { | ||
105 | u32 tmp; | ||
106 | dev_dbg(u3d->dev, "%s\n", __func__); | ||
107 | |||
108 | /* set TX and RX to stall */ | ||
109 | tmp = ioread32(&u3d->vuc_regs->epcr[0].epxoutcr0); | ||
110 | tmp |= MV_U3D_EPXCR_EP_HALT; | ||
111 | iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxoutcr0); | ||
112 | |||
113 | tmp = ioread32(&u3d->vuc_regs->epcr[0].epxincr0); | ||
114 | tmp |= MV_U3D_EPXCR_EP_HALT; | ||
115 | iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxincr0); | ||
116 | |||
117 | /* update ep0 state */ | ||
118 | u3d->ep0_state = MV_U3D_WAIT_FOR_SETUP; | ||
119 | u3d->ep0_dir = MV_U3D_EP_DIR_OUT; | ||
120 | } | ||
121 | |||
122 | static int mv_u3d_process_ep_req(struct mv_u3d *u3d, int index, | ||
123 | struct mv_u3d_req *curr_req) | ||
124 | { | ||
125 | struct mv_u3d_trb *curr_trb; | ||
126 | dma_addr_t cur_deq_lo; | ||
127 | struct mv_u3d_ep_context *curr_ep_context; | ||
128 | int trb_complete, actual, remaining_length; | ||
129 | int direction, ep_num; | ||
130 | int retval = 0; | ||
131 | u32 tmp, status, length; | ||
132 | |||
133 | curr_ep_context = &u3d->ep_context[index]; | ||
134 | direction = index % 2; | ||
135 | ep_num = index / 2; | ||
136 | |||
137 | trb_complete = 0; | ||
138 | actual = curr_req->req.length; | ||
139 | |||
140 | while (!list_empty(&curr_req->trb_list)) { | ||
141 | curr_trb = list_entry(curr_req->trb_list.next, | ||
142 | struct mv_u3d_trb, trb_list); | ||
143 | if (!curr_trb->trb_hw->ctrl.own) { | ||
144 | dev_err(u3d->dev, "%s, TRB own error!\n", | ||
145 | u3d->eps[index].name); | ||
146 | return 1; | ||
147 | } | ||
148 | |||
149 | curr_trb->trb_hw->ctrl.own = 0; | ||
150 | if (direction == MV_U3D_EP_DIR_OUT) { | ||
151 | tmp = ioread32(&u3d->vuc_regs->rxst[ep_num].statuslo); | ||
152 | cur_deq_lo = | ||
153 | ioread32(&u3d->vuc_regs->rxst[ep_num].curdeqlo); | ||
154 | } else { | ||
155 | tmp = ioread32(&u3d->vuc_regs->txst[ep_num].statuslo); | ||
156 | cur_deq_lo = | ||
157 | ioread32(&u3d->vuc_regs->txst[ep_num].curdeqlo); | ||
158 | } | ||
159 | |||
160 | status = tmp >> MV_U3D_XFERSTATUS_COMPLETE_SHIFT; | ||
161 | length = tmp & MV_U3D_XFERSTATUS_TRB_LENGTH_MASK; | ||
162 | |||
163 | if (status == MV_U3D_COMPLETE_SUCCESS || | ||
164 | (status == MV_U3D_COMPLETE_SHORT_PACKET && | ||
165 | direction == MV_U3D_EP_DIR_OUT)) { | ||
166 | remaining_length += length; | ||
167 | actual -= remaining_length; | ||
168 | } else { | ||
169 | dev_err(u3d->dev, | ||
170 | "complete_tr error: ep=%d %s: error = 0x%x\n", | ||
171 | index >> 1, direction ? "SEND" : "RECV", | ||
172 | status); | ||
173 | retval = -EPROTO; | ||
174 | } | ||
175 | |||
176 | list_del_init(&curr_trb->trb_list); | ||
177 | } | ||
178 | if (retval) | ||
179 | return retval; | ||
180 | |||
181 | curr_req->req.actual = actual; | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * mv_u3d_done() - retire a request; caller blocked irqs | ||
187 | * @status : request status to be set, only works when | ||
188 | * request is still in progress. | ||
189 | */ | ||
190 | static | ||
191 | void mv_u3d_done(struct mv_u3d_ep *ep, struct mv_u3d_req *req, int status) | ||
192 | { | ||
193 | struct mv_u3d *u3d = (struct mv_u3d *)ep->u3d; | ||
194 | |||
195 | dev_dbg(u3d->dev, "mv_u3d_done: remove req->queue\n"); | ||
196 | /* Removed the req from ep queue */ | ||
197 | list_del_init(&req->queue); | ||
198 | |||
199 | /* req.status should be set as -EINPROGRESS in ep_queue() */ | ||
200 | if (req->req.status == -EINPROGRESS) | ||
201 | req->req.status = status; | ||
202 | else | ||
203 | status = req->req.status; | ||
204 | |||
205 | /* Free trb for the request */ | ||
206 | if (!req->chain) | ||
207 | dma_pool_free(u3d->trb_pool, | ||
208 | req->trb_head->trb_hw, req->trb_head->trb_dma); | ||
209 | else { | ||
210 | dma_unmap_single(ep->u3d->gadget.dev.parent, | ||
211 | (dma_addr_t)req->trb_head->trb_dma, | ||
212 | req->trb_count * sizeof(struct mv_u3d_trb_hw), | ||
213 | DMA_BIDIRECTIONAL); | ||
214 | kfree(req->trb_head->trb_hw); | ||
215 | } | ||
216 | kfree(req->trb_head); | ||
217 | |||
218 | usb_gadget_unmap_request(&u3d->gadget, &req->req, mv_u3d_ep_dir(ep)); | ||
219 | |||
220 | if (status && (status != -ESHUTDOWN)) { | ||
221 | dev_dbg(u3d->dev, "complete %s req %p stat %d len %u/%u", | ||
222 | ep->ep.name, &req->req, status, | ||
223 | req->req.actual, req->req.length); | ||
224 | } | ||
225 | |||
226 | spin_unlock(&ep->u3d->lock); | ||
227 | /* | ||
228 | * complete() is from gadget layer, | ||
229 | * eg fsg->bulk_in_complete() | ||
230 | */ | ||
231 | if (req->req.complete) | ||
232 | req->req.complete(&ep->ep, &req->req); | ||
233 | |||
234 | spin_lock(&ep->u3d->lock); | ||
235 | } | ||
236 | |||
237 | static int mv_u3d_queue_trb(struct mv_u3d_ep *ep, struct mv_u3d_req *req) | ||
238 | { | ||
239 | u32 tmp, direction; | ||
240 | struct mv_u3d *u3d; | ||
241 | struct mv_u3d_ep_context *ep_context; | ||
242 | int retval = 0; | ||
243 | |||
244 | u3d = ep->u3d; | ||
245 | direction = mv_u3d_ep_dir(ep); | ||
246 | |||
247 | /* ep0 in and out share the same ep context slot 1*/ | ||
248 | if (ep->ep_num == 0) | ||
249 | ep_context = &(u3d->ep_context[1]); | ||
250 | else | ||
251 | ep_context = &(u3d->ep_context[ep->ep_num * 2 + direction]); | ||
252 | |||
253 | /* check if the pipe is empty or not */ | ||
254 | if (!list_empty(&ep->queue)) { | ||
255 | dev_err(u3d->dev, "add trb to non-empty queue!\n"); | ||
256 | retval = -ENOMEM; | ||
257 | WARN_ON(1); | ||
258 | } else { | ||
259 | ep_context->rsvd0 = cpu_to_le32(1); | ||
260 | ep_context->rsvd1 = 0; | ||
261 | |||
262 | /* Configure the trb address and set the DCS bit. | ||
263 | * Both DCS bit and own bit in trb should be set. | ||
264 | */ | ||
265 | ep_context->trb_addr_lo = | ||
266 | cpu_to_le32(req->trb_head->trb_dma | DCS_ENABLE); | ||
267 | ep_context->trb_addr_hi = 0; | ||
268 | |||
269 | /* Ensure that updates to the EP Context will | ||
270 | * occure before Ring Bell. | ||
271 | */ | ||
272 | wmb(); | ||
273 | |||
274 | /* ring bell the ep */ | ||
275 | if (ep->ep_num == 0) | ||
276 | tmp = 0x1; | ||
277 | else | ||
278 | tmp = ep->ep_num * 2 | ||
279 | + ((direction == MV_U3D_EP_DIR_OUT) ? 0 : 1); | ||
280 | |||
281 | iowrite32(tmp, &u3d->op_regs->doorbell); | ||
282 | } | ||
283 | return retval; | ||
284 | } | ||
285 | |||
286 | static struct mv_u3d_trb *mv_u3d_build_trb_one(struct mv_u3d_req *req, | ||
287 | unsigned *length, dma_addr_t *dma) | ||
288 | { | ||
289 | u32 temp; | ||
290 | unsigned int direction; | ||
291 | struct mv_u3d_trb *trb; | ||
292 | struct mv_u3d_trb_hw *trb_hw; | ||
293 | struct mv_u3d *u3d; | ||
294 | |||
295 | /* how big will this transfer be? */ | ||
296 | *length = req->req.length - req->req.actual; | ||
297 | BUG_ON(*length > (unsigned)MV_U3D_EP_MAX_LENGTH_TRANSFER); | ||
298 | |||
299 | u3d = req->ep->u3d; | ||
300 | |||
301 | trb = kzalloc(sizeof(*trb), GFP_ATOMIC); | ||
302 | if (!trb) { | ||
303 | dev_err(u3d->dev, "%s, trb alloc fail\n", __func__); | ||
304 | return NULL; | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * Be careful that no _GFP_HIGHMEM is set, | ||
309 | * or we can not use dma_to_virt | ||
310 | * cannot use GFP_KERNEL in spin lock | ||
311 | */ | ||
312 | trb_hw = dma_pool_alloc(u3d->trb_pool, GFP_ATOMIC, dma); | ||
313 | if (!trb_hw) { | ||
314 | dev_err(u3d->dev, | ||
315 | "%s, dma_pool_alloc fail\n", __func__); | ||
316 | return NULL; | ||
317 | } | ||
318 | trb->trb_dma = *dma; | ||
319 | trb->trb_hw = trb_hw; | ||
320 | |||
321 | /* initialize buffer page pointers */ | ||
322 | temp = (u32)(req->req.dma + req->req.actual); | ||
323 | |||
324 | trb_hw->buf_addr_lo = cpu_to_le32(temp); | ||
325 | trb_hw->buf_addr_hi = 0; | ||
326 | trb_hw->trb_len = cpu_to_le32(*length); | ||
327 | trb_hw->ctrl.own = 1; | ||
328 | |||
329 | if (req->ep->ep_num == 0) | ||
330 | trb_hw->ctrl.type = TYPE_DATA; | ||
331 | else | ||
332 | trb_hw->ctrl.type = TYPE_NORMAL; | ||
333 | |||
334 | req->req.actual += *length; | ||
335 | |||
336 | direction = mv_u3d_ep_dir(req->ep); | ||
337 | if (direction == MV_U3D_EP_DIR_IN) | ||
338 | trb_hw->ctrl.dir = 1; | ||
339 | else | ||
340 | trb_hw->ctrl.dir = 0; | ||
341 | |||
342 | /* Enable interrupt for the last trb of a request */ | ||
343 | if (!req->req.no_interrupt) | ||
344 | trb_hw->ctrl.ioc = 1; | ||
345 | |||
346 | trb_hw->ctrl.chain = 0; | ||
347 | |||
348 | wmb(); | ||
349 | return trb; | ||
350 | } | ||
351 | |||
352 | static int mv_u3d_build_trb_chain(struct mv_u3d_req *req, unsigned *length, | ||
353 | struct mv_u3d_trb *trb, int *is_last) | ||
354 | { | ||
355 | u32 temp; | ||
356 | unsigned int direction; | ||
357 | struct mv_u3d *u3d; | ||
358 | |||
359 | /* how big will this transfer be? */ | ||
360 | *length = min(req->req.length - req->req.actual, | ||
361 | (unsigned)MV_U3D_EP_MAX_LENGTH_TRANSFER); | ||
362 | |||
363 | u3d = req->ep->u3d; | ||
364 | |||
365 | trb->trb_dma = 0; | ||
366 | |||
367 | /* initialize buffer page pointers */ | ||
368 | temp = (u32)(req->req.dma + req->req.actual); | ||
369 | |||
370 | trb->trb_hw->buf_addr_lo = cpu_to_le32(temp); | ||
371 | trb->trb_hw->buf_addr_hi = 0; | ||
372 | trb->trb_hw->trb_len = cpu_to_le32(*length); | ||
373 | trb->trb_hw->ctrl.own = 1; | ||
374 | |||
375 | if (req->ep->ep_num == 0) | ||
376 | trb->trb_hw->ctrl.type = TYPE_DATA; | ||
377 | else | ||
378 | trb->trb_hw->ctrl.type = TYPE_NORMAL; | ||
379 | |||
380 | req->req.actual += *length; | ||
381 | |||
382 | direction = mv_u3d_ep_dir(req->ep); | ||
383 | if (direction == MV_U3D_EP_DIR_IN) | ||
384 | trb->trb_hw->ctrl.dir = 1; | ||
385 | else | ||
386 | trb->trb_hw->ctrl.dir = 0; | ||
387 | |||
388 | /* zlp is needed if req->req.zero is set */ | ||
389 | if (req->req.zero) { | ||
390 | if (*length == 0 || (*length % req->ep->ep.maxpacket) != 0) | ||
391 | *is_last = 1; | ||
392 | else | ||
393 | *is_last = 0; | ||
394 | } else if (req->req.length == req->req.actual) | ||
395 | *is_last = 1; | ||
396 | else | ||
397 | *is_last = 0; | ||
398 | |||
399 | /* Enable interrupt for the last trb of a request */ | ||
400 | if (*is_last && !req->req.no_interrupt) | ||
401 | trb->trb_hw->ctrl.ioc = 1; | ||
402 | |||
403 | if (*is_last) | ||
404 | trb->trb_hw->ctrl.chain = 0; | ||
405 | else { | ||
406 | trb->trb_hw->ctrl.chain = 1; | ||
407 | dev_dbg(u3d->dev, "chain trb\n"); | ||
408 | } | ||
409 | |||
410 | wmb(); | ||
411 | |||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | /* generate TRB linked list for a request | ||
416 | * usb controller only supports continous trb chain, | ||
417 | * that trb structure physical address should be continous. | ||
418 | */ | ||
419 | static int mv_u3d_req_to_trb(struct mv_u3d_req *req) | ||
420 | { | ||
421 | unsigned count; | ||
422 | int is_last; | ||
423 | struct mv_u3d_trb *trb; | ||
424 | struct mv_u3d_trb_hw *trb_hw; | ||
425 | struct mv_u3d *u3d; | ||
426 | dma_addr_t dma; | ||
427 | unsigned length; | ||
428 | unsigned trb_num; | ||
429 | |||
430 | u3d = req->ep->u3d; | ||
431 | |||
432 | INIT_LIST_HEAD(&req->trb_list); | ||
433 | |||
434 | length = req->req.length - req->req.actual; | ||
435 | /* normally the request transfer length is less than 16KB. | ||
436 | * we use buil_trb_one() to optimize it. | ||
437 | */ | ||
438 | if (length <= (unsigned)MV_U3D_EP_MAX_LENGTH_TRANSFER) { | ||
439 | trb = mv_u3d_build_trb_one(req, &count, &dma); | ||
440 | list_add_tail(&trb->trb_list, &req->trb_list); | ||
441 | req->trb_head = trb; | ||
442 | req->trb_count = 1; | ||
443 | req->chain = 0; | ||
444 | } else { | ||
445 | trb_num = length / MV_U3D_EP_MAX_LENGTH_TRANSFER; | ||
446 | if (length % MV_U3D_EP_MAX_LENGTH_TRANSFER) | ||
447 | trb_num++; | ||
448 | |||
449 | trb = kcalloc(trb_num, sizeof(*trb), GFP_ATOMIC); | ||
450 | if (!trb) { | ||
451 | dev_err(u3d->dev, | ||
452 | "%s, trb alloc fail\n", __func__); | ||
453 | return -ENOMEM; | ||
454 | } | ||
455 | |||
456 | trb_hw = kcalloc(trb_num, sizeof(*trb_hw), GFP_ATOMIC); | ||
457 | if (!trb_hw) { | ||
458 | dev_err(u3d->dev, | ||
459 | "%s, trb_hw alloc fail\n", __func__); | ||
460 | return -ENOMEM; | ||
461 | } | ||
462 | |||
463 | do { | ||
464 | trb->trb_hw = trb_hw; | ||
465 | if (mv_u3d_build_trb_chain(req, &count, | ||
466 | trb, &is_last)) { | ||
467 | dev_err(u3d->dev, | ||
468 | "%s, mv_u3d_build_trb_chain fail\n", | ||
469 | __func__); | ||
470 | return -EIO; | ||
471 | } | ||
472 | |||
473 | list_add_tail(&trb->trb_list, &req->trb_list); | ||
474 | req->trb_count++; | ||
475 | trb++; | ||
476 | trb_hw++; | ||
477 | } while (!is_last); | ||
478 | |||
479 | req->trb_head = list_entry(req->trb_list.next, | ||
480 | struct mv_u3d_trb, trb_list); | ||
481 | req->trb_head->trb_dma = dma_map_single(u3d->gadget.dev.parent, | ||
482 | req->trb_head->trb_hw, | ||
483 | trb_num * sizeof(*trb_hw), | ||
484 | DMA_BIDIRECTIONAL); | ||
485 | |||
486 | req->chain = 1; | ||
487 | } | ||
488 | |||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static int | ||
493 | mv_u3d_start_queue(struct mv_u3d_ep *ep) | ||
494 | { | ||
495 | struct mv_u3d *u3d = ep->u3d; | ||
496 | struct mv_u3d_req *req; | ||
497 | int ret; | ||
498 | |||
499 | if (!list_empty(&ep->req_list) && !ep->processing) | ||
500 | req = list_entry(ep->req_list.next, struct mv_u3d_req, list); | ||
501 | else | ||
502 | return 0; | ||
503 | |||
504 | ep->processing = 1; | ||
505 | |||
506 | /* set up dma mapping */ | ||
507 | ret = usb_gadget_map_request(&u3d->gadget, &req->req, | ||
508 | mv_u3d_ep_dir(ep)); | ||
509 | if (ret) | ||
510 | return ret; | ||
511 | |||
512 | req->req.status = -EINPROGRESS; | ||
513 | req->req.actual = 0; | ||
514 | req->trb_count = 0; | ||
515 | |||
516 | /* build trbs and push them to device queue */ | ||
517 | if (!mv_u3d_req_to_trb(req)) { | ||
518 | ret = mv_u3d_queue_trb(ep, req); | ||
519 | if (ret) { | ||
520 | ep->processing = 0; | ||
521 | return ret; | ||
522 | } | ||
523 | } else { | ||
524 | ep->processing = 0; | ||
525 | dev_err(u3d->dev, "%s, mv_u3d_req_to_trb fail\n", __func__); | ||
526 | return -ENOMEM; | ||
527 | } | ||
528 | |||
529 | /* irq handler advances the queue */ | ||
530 | if (req) | ||
531 | list_add_tail(&req->queue, &ep->queue); | ||
532 | |||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static int mv_u3d_ep_enable(struct usb_ep *_ep, | ||
537 | const struct usb_endpoint_descriptor *desc) | ||
538 | { | ||
539 | struct mv_u3d *u3d; | ||
540 | struct mv_u3d_ep *ep; | ||
541 | struct mv_u3d_ep_context *ep_context; | ||
542 | u16 max = 0; | ||
543 | unsigned maxburst = 0; | ||
544 | u32 epxcr, direction; | ||
545 | |||
546 | if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) | ||
547 | return -EINVAL; | ||
548 | |||
549 | ep = container_of(_ep, struct mv_u3d_ep, ep); | ||
550 | u3d = ep->u3d; | ||
551 | |||
552 | if (!u3d->driver || u3d->gadget.speed == USB_SPEED_UNKNOWN) | ||
553 | return -ESHUTDOWN; | ||
554 | |||
555 | direction = mv_u3d_ep_dir(ep); | ||
556 | max = le16_to_cpu(desc->wMaxPacketSize); | ||
557 | |||
558 | if (!_ep->maxburst) | ||
559 | _ep->maxburst = 1; | ||
560 | maxburst = _ep->maxburst; | ||
561 | |||
562 | /* Get the endpoint context address */ | ||
563 | ep_context = (struct mv_u3d_ep_context *)ep->ep_context; | ||
564 | |||
565 | /* Set the max burst size */ | ||
566 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
567 | case USB_ENDPOINT_XFER_BULK: | ||
568 | if (maxburst > 16) { | ||
569 | dev_dbg(u3d->dev, | ||
570 | "max burst should not be greater " | ||
571 | "than 16 on bulk ep\n"); | ||
572 | maxburst = 1; | ||
573 | _ep->maxburst = maxburst; | ||
574 | } | ||
575 | dev_dbg(u3d->dev, | ||
576 | "maxburst: %d on bulk %s\n", maxburst, ep->name); | ||
577 | break; | ||
578 | case USB_ENDPOINT_XFER_CONTROL: | ||
579 | /* control transfer only supports maxburst as one */ | ||
580 | maxburst = 1; | ||
581 | _ep->maxburst = maxburst; | ||
582 | break; | ||
583 | case USB_ENDPOINT_XFER_INT: | ||
584 | if (maxburst != 1) { | ||
585 | dev_dbg(u3d->dev, | ||
586 | "max burst should be 1 on int ep " | ||
587 | "if transfer size is not 1024\n"); | ||
588 | maxburst = 1; | ||
589 | _ep->maxburst = maxburst; | ||
590 | } | ||
591 | break; | ||
592 | case USB_ENDPOINT_XFER_ISOC: | ||
593 | if (maxburst != 1) { | ||
594 | dev_dbg(u3d->dev, | ||
595 | "max burst should be 1 on isoc ep " | ||
596 | "if transfer size is not 1024\n"); | ||
597 | maxburst = 1; | ||
598 | _ep->maxburst = maxburst; | ||
599 | } | ||
600 | break; | ||
601 | default: | ||
602 | goto en_done; | ||
603 | } | ||
604 | |||
605 | ep->ep.maxpacket = max; | ||
606 | ep->ep.desc = desc; | ||
607 | ep->enabled = 1; | ||
608 | |||
609 | /* Enable the endpoint for Rx or Tx and set the endpoint type */ | ||
610 | if (direction == MV_U3D_EP_DIR_OUT) { | ||
611 | epxcr = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); | ||
612 | epxcr |= MV_U3D_EPXCR_EP_INIT; | ||
613 | iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); | ||
614 | udelay(5); | ||
615 | epxcr &= ~MV_U3D_EPXCR_EP_INIT; | ||
616 | iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); | ||
617 | |||
618 | epxcr = ((max << MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT) | ||
619 | | ((maxburst - 1) << MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT) | ||
620 | | (1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) | ||
621 | | (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)); | ||
622 | iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr1); | ||
623 | } else { | ||
624 | epxcr = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxincr0); | ||
625 | epxcr |= MV_U3D_EPXCR_EP_INIT; | ||
626 | iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxincr0); | ||
627 | udelay(5); | ||
628 | epxcr &= ~MV_U3D_EPXCR_EP_INIT; | ||
629 | iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxincr0); | ||
630 | |||
631 | epxcr = ((max << MV_U3D_EPXCR_MAX_PACKET_SIZE_SHIFT) | ||
632 | | ((maxburst - 1) << MV_U3D_EPXCR_MAX_BURST_SIZE_SHIFT) | ||
633 | | (1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) | ||
634 | | (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)); | ||
635 | iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxincr1); | ||
636 | } | ||
637 | |||
638 | return 0; | ||
639 | en_done: | ||
640 | return -EINVAL; | ||
641 | } | ||
642 | |||
643 | static int mv_u3d_ep_disable(struct usb_ep *_ep) | ||
644 | { | ||
645 | struct mv_u3d *u3d; | ||
646 | struct mv_u3d_ep *ep; | ||
647 | struct mv_u3d_ep_context *ep_context; | ||
648 | u32 epxcr, direction; | ||
649 | |||
650 | if (!_ep) | ||
651 | return -EINVAL; | ||
652 | |||
653 | ep = container_of(_ep, struct mv_u3d_ep, ep); | ||
654 | if (!ep->ep.desc) | ||
655 | return -EINVAL; | ||
656 | |||
657 | u3d = ep->u3d; | ||
658 | |||
659 | /* Get the endpoint context address */ | ||
660 | ep_context = ep->ep_context; | ||
661 | |||
662 | direction = mv_u3d_ep_dir(ep); | ||
663 | |||
664 | /* nuke all pending requests (does flush) */ | ||
665 | mv_u3d_nuke(ep, -ESHUTDOWN); | ||
666 | |||
667 | /* Disable the endpoint for Rx or Tx and reset the endpoint type */ | ||
668 | if (direction == MV_U3D_EP_DIR_OUT) { | ||
669 | epxcr = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxoutcr1); | ||
670 | epxcr &= ~((1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) | ||
671 | | USB_ENDPOINT_XFERTYPE_MASK); | ||
672 | iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr1); | ||
673 | } else { | ||
674 | epxcr = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxincr1); | ||
675 | epxcr &= ~((1 << MV_U3D_EPXCR_EP_ENABLE_SHIFT) | ||
676 | | USB_ENDPOINT_XFERTYPE_MASK); | ||
677 | iowrite32(epxcr, &u3d->vuc_regs->epcr[ep->ep_num].epxincr1); | ||
678 | } | ||
679 | |||
680 | ep->enabled = 0; | ||
681 | |||
682 | ep->ep.desc = NULL; | ||
683 | return 0; | ||
684 | } | ||
685 | |||
686 | static struct usb_request * | ||
687 | mv_u3d_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) | ||
688 | { | ||
689 | struct mv_u3d_req *req = NULL; | ||
690 | |||
691 | req = kzalloc(sizeof *req, gfp_flags); | ||
692 | if (!req) | ||
693 | return NULL; | ||
694 | |||
695 | INIT_LIST_HEAD(&req->queue); | ||
696 | |||
697 | return &req->req; | ||
698 | } | ||
699 | |||
700 | static void mv_u3d_free_request(struct usb_ep *_ep, struct usb_request *_req) | ||
701 | { | ||
702 | struct mv_u3d_req *req = container_of(_req, struct mv_u3d_req, req); | ||
703 | |||
704 | kfree(req); | ||
705 | } | ||
706 | |||
707 | static void mv_u3d_ep_fifo_flush(struct usb_ep *_ep) | ||
708 | { | ||
709 | struct mv_u3d *u3d; | ||
710 | u32 direction; | ||
711 | struct mv_u3d_ep *ep = container_of(_ep, struct mv_u3d_ep, ep); | ||
712 | unsigned int loops; | ||
713 | u32 tmp; | ||
714 | |||
715 | /* if endpoint is not enabled, cannot flush endpoint */ | ||
716 | if (!ep->enabled) | ||
717 | return; | ||
718 | |||
719 | u3d = ep->u3d; | ||
720 | direction = mv_u3d_ep_dir(ep); | ||
721 | |||
722 | /* ep0 need clear bit after flushing fifo. */ | ||
723 | if (!ep->ep_num) { | ||
724 | if (direction == MV_U3D_EP_DIR_OUT) { | ||
725 | tmp = ioread32(&u3d->vuc_regs->epcr[0].epxoutcr0); | ||
726 | tmp |= MV_U3D_EPXCR_EP_FLUSH; | ||
727 | iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxoutcr0); | ||
728 | udelay(10); | ||
729 | tmp &= ~MV_U3D_EPXCR_EP_FLUSH; | ||
730 | iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxoutcr0); | ||
731 | } else { | ||
732 | tmp = ioread32(&u3d->vuc_regs->epcr[0].epxincr0); | ||
733 | tmp |= MV_U3D_EPXCR_EP_FLUSH; | ||
734 | iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxincr0); | ||
735 | udelay(10); | ||
736 | tmp &= ~MV_U3D_EPXCR_EP_FLUSH; | ||
737 | iowrite32(tmp, &u3d->vuc_regs->epcr[0].epxincr0); | ||
738 | } | ||
739 | return; | ||
740 | } | ||
741 | |||
742 | if (direction == MV_U3D_EP_DIR_OUT) { | ||
743 | tmp = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); | ||
744 | tmp |= MV_U3D_EPXCR_EP_FLUSH; | ||
745 | iowrite32(tmp, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); | ||
746 | |||
747 | /* Wait until flushing completed */ | ||
748 | loops = LOOPS(MV_U3D_FLUSH_TIMEOUT); | ||
749 | while (ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0) & | ||
750 | MV_U3D_EPXCR_EP_FLUSH) { | ||
751 | /* | ||
752 | * EP_FLUSH bit should be cleared to indicate this | ||
753 | * operation is complete | ||
754 | */ | ||
755 | if (loops == 0) { | ||
756 | dev_dbg(u3d->dev, | ||
757 | "EP FLUSH TIMEOUT for ep%d%s\n", ep->ep_num, | ||
758 | direction ? "in" : "out"); | ||
759 | return; | ||
760 | } | ||
761 | loops--; | ||
762 | udelay(LOOPS_USEC); | ||
763 | } | ||
764 | } else { /* EP_DIR_IN */ | ||
765 | tmp = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxincr0); | ||
766 | tmp |= MV_U3D_EPXCR_EP_FLUSH; | ||
767 | iowrite32(tmp, &u3d->vuc_regs->epcr[ep->ep_num].epxincr0); | ||
768 | |||
769 | /* Wait until flushing completed */ | ||
770 | loops = LOOPS(MV_U3D_FLUSH_TIMEOUT); | ||
771 | while (ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxincr0) & | ||
772 | MV_U3D_EPXCR_EP_FLUSH) { | ||
773 | /* | ||
774 | * EP_FLUSH bit should be cleared to indicate this | ||
775 | * operation is complete | ||
776 | */ | ||
777 | if (loops == 0) { | ||
778 | dev_dbg(u3d->dev, | ||
779 | "EP FLUSH TIMEOUT for ep%d%s\n", ep->ep_num, | ||
780 | direction ? "in" : "out"); | ||
781 | return; | ||
782 | } | ||
783 | loops--; | ||
784 | udelay(LOOPS_USEC); | ||
785 | } | ||
786 | } | ||
787 | } | ||
788 | |||
789 | /* queues (submits) an I/O request to an endpoint */ | ||
790 | static int | ||
791 | mv_u3d_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | ||
792 | { | ||
793 | struct mv_u3d_ep *ep; | ||
794 | struct mv_u3d_req *req; | ||
795 | struct mv_u3d *u3d; | ||
796 | unsigned long flags; | ||
797 | int is_first_req = 0; | ||
798 | |||
799 | if (unlikely(!_ep || !_req)) | ||
800 | return -EINVAL; | ||
801 | |||
802 | ep = container_of(_ep, struct mv_u3d_ep, ep); | ||
803 | u3d = ep->u3d; | ||
804 | |||
805 | req = container_of(_req, struct mv_u3d_req, req); | ||
806 | |||
807 | if (!ep->ep_num | ||
808 | && u3d->ep0_state == MV_U3D_STATUS_STAGE | ||
809 | && !_req->length) { | ||
810 | dev_dbg(u3d->dev, "ep0 status stage\n"); | ||
811 | u3d->ep0_state = MV_U3D_WAIT_FOR_SETUP; | ||
812 | return 0; | ||
813 | } | ||
814 | |||
815 | dev_dbg(u3d->dev, "%s: %s, req: 0x%x\n", | ||
816 | __func__, _ep->name, (u32)req); | ||
817 | |||
818 | /* catch various bogus parameters */ | ||
819 | if (!req->req.complete || !req->req.buf | ||
820 | || !list_empty(&req->queue)) { | ||
821 | dev_err(u3d->dev, | ||
822 | "%s, bad params, _req: 0x%x," | ||
823 | "req->req.complete: 0x%x, req->req.buf: 0x%x," | ||
824 | "list_empty: 0x%x\n", | ||
825 | __func__, (u32)_req, | ||
826 | (u32)req->req.complete, (u32)req->req.buf, | ||
827 | (u32)list_empty(&req->queue)); | ||
828 | return -EINVAL; | ||
829 | } | ||
830 | if (unlikely(!ep->ep.desc)) { | ||
831 | dev_err(u3d->dev, "%s, bad ep\n", __func__); | ||
832 | return -EINVAL; | ||
833 | } | ||
834 | if (ep->ep.desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { | ||
835 | if (req->req.length > ep->ep.maxpacket) | ||
836 | return -EMSGSIZE; | ||
837 | } | ||
838 | |||
839 | if (!u3d->driver || u3d->gadget.speed == USB_SPEED_UNKNOWN) { | ||
840 | dev_err(u3d->dev, | ||
841 | "bad params of driver/speed\n"); | ||
842 | return -ESHUTDOWN; | ||
843 | } | ||
844 | |||
845 | req->ep = ep; | ||
846 | |||
847 | /* Software list handles usb request. */ | ||
848 | spin_lock_irqsave(&ep->req_lock, flags); | ||
849 | is_first_req = list_empty(&ep->req_list); | ||
850 | list_add_tail(&req->list, &ep->req_list); | ||
851 | spin_unlock_irqrestore(&ep->req_lock, flags); | ||
852 | if (!is_first_req) { | ||
853 | dev_dbg(u3d->dev, "list is not empty\n"); | ||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | dev_dbg(u3d->dev, "call mv_u3d_start_queue from usb_ep_queue\n"); | ||
858 | spin_lock_irqsave(&u3d->lock, flags); | ||
859 | mv_u3d_start_queue(ep); | ||
860 | spin_unlock_irqrestore(&u3d->lock, flags); | ||
861 | return 0; | ||
862 | } | ||
863 | |||
864 | /* dequeues (cancels, unlinks) an I/O request from an endpoint */ | ||
865 | static int mv_u3d_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
866 | { | ||
867 | struct mv_u3d_ep *ep; | ||
868 | struct mv_u3d_req *req; | ||
869 | struct mv_u3d *u3d; | ||
870 | struct mv_u3d_ep_context *ep_context; | ||
871 | struct mv_u3d_req *next_req; | ||
872 | |||
873 | unsigned long flags; | ||
874 | int ret = 0; | ||
875 | |||
876 | if (!_ep || !_req) | ||
877 | return -EINVAL; | ||
878 | |||
879 | ep = container_of(_ep, struct mv_u3d_ep, ep); | ||
880 | u3d = ep->u3d; | ||
881 | |||
882 | spin_lock_irqsave(&ep->u3d->lock, flags); | ||
883 | |||
884 | /* make sure it's actually queued on this endpoint */ | ||
885 | list_for_each_entry(req, &ep->queue, queue) { | ||
886 | if (&req->req == _req) | ||
887 | break; | ||
888 | } | ||
889 | if (&req->req != _req) { | ||
890 | ret = -EINVAL; | ||
891 | goto out; | ||
892 | } | ||
893 | |||
894 | /* The request is in progress, or completed but not dequeued */ | ||
895 | if (ep->queue.next == &req->queue) { | ||
896 | _req->status = -ECONNRESET; | ||
897 | mv_u3d_ep_fifo_flush(_ep); | ||
898 | |||
899 | /* The request isn't the last request in this ep queue */ | ||
900 | if (req->queue.next != &ep->queue) { | ||
901 | dev_dbg(u3d->dev, | ||
902 | "it is the last request in this ep queue\n"); | ||
903 | ep_context = ep->ep_context; | ||
904 | next_req = list_entry(req->queue.next, | ||
905 | struct mv_u3d_req, queue); | ||
906 | |||
907 | /* Point first TRB of next request to the EP context. */ | ||
908 | iowrite32((u32) next_req->trb_head, | ||
909 | &ep_context->trb_addr_lo); | ||
910 | } else { | ||
911 | struct mv_u3d_ep_context *ep_context; | ||
912 | ep_context = ep->ep_context; | ||
913 | ep_context->trb_addr_lo = 0; | ||
914 | ep_context->trb_addr_hi = 0; | ||
915 | } | ||
916 | |||
917 | } else | ||
918 | WARN_ON(1); | ||
919 | |||
920 | mv_u3d_done(ep, req, -ECONNRESET); | ||
921 | |||
922 | /* remove the req from the ep req list */ | ||
923 | if (!list_empty(&ep->req_list)) { | ||
924 | struct mv_u3d_req *curr_req; | ||
925 | curr_req = list_entry(ep->req_list.next, | ||
926 | struct mv_u3d_req, list); | ||
927 | if (curr_req == req) { | ||
928 | list_del_init(&req->list); | ||
929 | ep->processing = 0; | ||
930 | } | ||
931 | } | ||
932 | |||
933 | out: | ||
934 | spin_unlock_irqrestore(&ep->u3d->lock, flags); | ||
935 | return ret; | ||
936 | } | ||
937 | |||
938 | static void | ||
939 | mv_u3d_ep_set_stall(struct mv_u3d *u3d, u8 ep_num, u8 direction, int stall) | ||
940 | { | ||
941 | u32 tmp; | ||
942 | struct mv_u3d_ep *ep = u3d->eps; | ||
943 | |||
944 | dev_dbg(u3d->dev, "%s\n", __func__); | ||
945 | if (direction == MV_U3D_EP_DIR_OUT) { | ||
946 | tmp = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); | ||
947 | if (stall) | ||
948 | tmp |= MV_U3D_EPXCR_EP_HALT; | ||
949 | else | ||
950 | tmp &= ~MV_U3D_EPXCR_EP_HALT; | ||
951 | iowrite32(tmp, &u3d->vuc_regs->epcr[ep->ep_num].epxoutcr0); | ||
952 | } else { | ||
953 | tmp = ioread32(&u3d->vuc_regs->epcr[ep->ep_num].epxincr0); | ||
954 | if (stall) | ||
955 | tmp |= MV_U3D_EPXCR_EP_HALT; | ||
956 | else | ||
957 | tmp &= ~MV_U3D_EPXCR_EP_HALT; | ||
958 | iowrite32(tmp, &u3d->vuc_regs->epcr[ep->ep_num].epxincr0); | ||
959 | } | ||
960 | } | ||
961 | |||
962 | static int mv_u3d_ep_set_halt_wedge(struct usb_ep *_ep, int halt, int wedge) | ||
963 | { | ||
964 | struct mv_u3d_ep *ep; | ||
965 | unsigned long flags = 0; | ||
966 | int status = 0; | ||
967 | struct mv_u3d *u3d; | ||
968 | |||
969 | ep = container_of(_ep, struct mv_u3d_ep, ep); | ||
970 | u3d = ep->u3d; | ||
971 | if (!ep->ep.desc) { | ||
972 | status = -EINVAL; | ||
973 | goto out; | ||
974 | } | ||
975 | |||
976 | if (ep->ep.desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { | ||
977 | status = -EOPNOTSUPP; | ||
978 | goto out; | ||
979 | } | ||
980 | |||
981 | /* | ||
982 | * Attempt to halt IN ep will fail if any transfer requests | ||
983 | * are still queue | ||
984 | */ | ||
985 | if (halt && (mv_u3d_ep_dir(ep) == MV_U3D_EP_DIR_IN) | ||
986 | && !list_empty(&ep->queue)) { | ||
987 | status = -EAGAIN; | ||
988 | goto out; | ||
989 | } | ||
990 | |||
991 | spin_lock_irqsave(&ep->u3d->lock, flags); | ||
992 | mv_u3d_ep_set_stall(u3d, ep->ep_num, mv_u3d_ep_dir(ep), halt); | ||
993 | if (halt && wedge) | ||
994 | ep->wedge = 1; | ||
995 | else if (!halt) | ||
996 | ep->wedge = 0; | ||
997 | spin_unlock_irqrestore(&ep->u3d->lock, flags); | ||
998 | |||
999 | if (ep->ep_num == 0) | ||
1000 | u3d->ep0_dir = MV_U3D_EP_DIR_OUT; | ||
1001 | out: | ||
1002 | return status; | ||
1003 | } | ||
1004 | |||
1005 | static int mv_u3d_ep_set_halt(struct usb_ep *_ep, int halt) | ||
1006 | { | ||
1007 | return mv_u3d_ep_set_halt_wedge(_ep, halt, 0); | ||
1008 | } | ||
1009 | |||
1010 | static int mv_u3d_ep_set_wedge(struct usb_ep *_ep) | ||
1011 | { | ||
1012 | return mv_u3d_ep_set_halt_wedge(_ep, 1, 1); | ||
1013 | } | ||
1014 | |||
1015 | static struct usb_ep_ops mv_u3d_ep_ops = { | ||
1016 | .enable = mv_u3d_ep_enable, | ||
1017 | .disable = mv_u3d_ep_disable, | ||
1018 | |||
1019 | .alloc_request = mv_u3d_alloc_request, | ||
1020 | .free_request = mv_u3d_free_request, | ||
1021 | |||
1022 | .queue = mv_u3d_ep_queue, | ||
1023 | .dequeue = mv_u3d_ep_dequeue, | ||
1024 | |||
1025 | .set_wedge = mv_u3d_ep_set_wedge, | ||
1026 | .set_halt = mv_u3d_ep_set_halt, | ||
1027 | .fifo_flush = mv_u3d_ep_fifo_flush, | ||
1028 | }; | ||
1029 | |||
1030 | static void mv_u3d_controller_stop(struct mv_u3d *u3d) | ||
1031 | { | ||
1032 | u32 tmp; | ||
1033 | |||
1034 | if (!u3d->clock_gating && u3d->vbus_valid_detect) | ||
1035 | iowrite32(MV_U3D_INTR_ENABLE_VBUS_VALID, | ||
1036 | &u3d->vuc_regs->intrenable); | ||
1037 | else | ||
1038 | iowrite32(0, &u3d->vuc_regs->intrenable); | ||
1039 | iowrite32(~0x0, &u3d->vuc_regs->endcomplete); | ||
1040 | iowrite32(~0x0, &u3d->vuc_regs->trbunderrun); | ||
1041 | iowrite32(~0x0, &u3d->vuc_regs->trbcomplete); | ||
1042 | iowrite32(~0x0, &u3d->vuc_regs->linkchange); | ||
1043 | iowrite32(0x1, &u3d->vuc_regs->setuplock); | ||
1044 | |||
1045 | /* Reset the RUN bit in the command register to stop USB */ | ||
1046 | tmp = ioread32(&u3d->op_regs->usbcmd); | ||
1047 | tmp &= ~MV_U3D_CMD_RUN_STOP; | ||
1048 | iowrite32(tmp, &u3d->op_regs->usbcmd); | ||
1049 | dev_dbg(u3d->dev, "after u3d_stop, USBCMD 0x%x\n", | ||
1050 | ioread32(&u3d->op_regs->usbcmd)); | ||
1051 | } | ||
1052 | |||
1053 | static void mv_u3d_controller_start(struct mv_u3d *u3d) | ||
1054 | { | ||
1055 | u32 usbintr; | ||
1056 | u32 temp; | ||
1057 | |||
1058 | /* enable link LTSSM state machine */ | ||
1059 | temp = ioread32(&u3d->vuc_regs->ltssm); | ||
1060 | temp |= MV_U3D_LTSSM_PHY_INIT_DONE; | ||
1061 | iowrite32(temp, &u3d->vuc_regs->ltssm); | ||
1062 | |||
1063 | /* Enable interrupts */ | ||
1064 | usbintr = MV_U3D_INTR_ENABLE_LINK_CHG | MV_U3D_INTR_ENABLE_TXDESC_ERR | | ||
1065 | MV_U3D_INTR_ENABLE_RXDESC_ERR | MV_U3D_INTR_ENABLE_TX_COMPLETE | | ||
1066 | MV_U3D_INTR_ENABLE_RX_COMPLETE | MV_U3D_INTR_ENABLE_SETUP | | ||
1067 | (u3d->vbus_valid_detect ? MV_U3D_INTR_ENABLE_VBUS_VALID : 0); | ||
1068 | iowrite32(usbintr, &u3d->vuc_regs->intrenable); | ||
1069 | |||
1070 | /* Enable ctrl ep */ | ||
1071 | iowrite32(0x1, &u3d->vuc_regs->ctrlepenable); | ||
1072 | |||
1073 | /* Set the Run bit in the command register */ | ||
1074 | iowrite32(MV_U3D_CMD_RUN_STOP, &u3d->op_regs->usbcmd); | ||
1075 | dev_dbg(u3d->dev, "after u3d_start, USBCMD 0x%x\n", | ||
1076 | ioread32(&u3d->op_regs->usbcmd)); | ||
1077 | } | ||
1078 | |||
1079 | static int mv_u3d_controller_reset(struct mv_u3d *u3d) | ||
1080 | { | ||
1081 | unsigned int loops; | ||
1082 | u32 tmp; | ||
1083 | |||
1084 | /* Stop the controller */ | ||
1085 | tmp = ioread32(&u3d->op_regs->usbcmd); | ||
1086 | tmp &= ~MV_U3D_CMD_RUN_STOP; | ||
1087 | iowrite32(tmp, &u3d->op_regs->usbcmd); | ||
1088 | |||
1089 | /* Reset the controller to get default values */ | ||
1090 | iowrite32(MV_U3D_CMD_CTRL_RESET, &u3d->op_regs->usbcmd); | ||
1091 | |||
1092 | /* wait for reset to complete */ | ||
1093 | loops = LOOPS(MV_U3D_RESET_TIMEOUT); | ||
1094 | while (ioread32(&u3d->op_regs->usbcmd) & MV_U3D_CMD_CTRL_RESET) { | ||
1095 | if (loops == 0) { | ||
1096 | dev_err(u3d->dev, | ||
1097 | "Wait for RESET completed TIMEOUT\n"); | ||
1098 | return -ETIMEDOUT; | ||
1099 | } | ||
1100 | loops--; | ||
1101 | udelay(LOOPS_USEC); | ||
1102 | } | ||
1103 | |||
1104 | /* Configure the Endpoint Context Address */ | ||
1105 | iowrite32(u3d->ep_context_dma, &u3d->op_regs->dcbaapl); | ||
1106 | iowrite32(0, &u3d->op_regs->dcbaaph); | ||
1107 | |||
1108 | return 0; | ||
1109 | } | ||
1110 | |||
1111 | static int mv_u3d_enable(struct mv_u3d *u3d) | ||
1112 | { | ||
1113 | struct mv_usb_platform_data *pdata = u3d->dev->platform_data; | ||
1114 | int retval; | ||
1115 | |||
1116 | if (u3d->active) | ||
1117 | return 0; | ||
1118 | |||
1119 | if (!u3d->clock_gating) { | ||
1120 | u3d->active = 1; | ||
1121 | return 0; | ||
1122 | } | ||
1123 | |||
1124 | dev_dbg(u3d->dev, "enable u3d\n"); | ||
1125 | clk_enable(u3d->clk); | ||
1126 | if (pdata->phy_init) { | ||
1127 | retval = pdata->phy_init(u3d->phy_regs); | ||
1128 | if (retval) { | ||
1129 | dev_err(u3d->dev, | ||
1130 | "init phy error %d\n", retval); | ||
1131 | clk_disable(u3d->clk); | ||
1132 | return retval; | ||
1133 | } | ||
1134 | } | ||
1135 | u3d->active = 1; | ||
1136 | |||
1137 | return 0; | ||
1138 | } | ||
1139 | |||
1140 | static void mv_u3d_disable(struct mv_u3d *u3d) | ||
1141 | { | ||
1142 | struct mv_usb_platform_data *pdata = u3d->dev->platform_data; | ||
1143 | if (u3d->clock_gating && u3d->active) { | ||
1144 | dev_dbg(u3d->dev, "disable u3d\n"); | ||
1145 | if (pdata->phy_deinit) | ||
1146 | pdata->phy_deinit(u3d->phy_regs); | ||
1147 | clk_disable(u3d->clk); | ||
1148 | u3d->active = 0; | ||
1149 | } | ||
1150 | } | ||
1151 | |||
1152 | static int mv_u3d_vbus_session(struct usb_gadget *gadget, int is_active) | ||
1153 | { | ||
1154 | struct mv_u3d *u3d; | ||
1155 | unsigned long flags; | ||
1156 | int retval = 0; | ||
1157 | |||
1158 | u3d = container_of(gadget, struct mv_u3d, gadget); | ||
1159 | |||
1160 | spin_lock_irqsave(&u3d->lock, flags); | ||
1161 | |||
1162 | u3d->vbus_active = (is_active != 0); | ||
1163 | dev_dbg(u3d->dev, "%s: softconnect %d, vbus_active %d\n", | ||
1164 | __func__, u3d->softconnect, u3d->vbus_active); | ||
1165 | /* | ||
1166 | * 1. external VBUS detect: we can disable/enable clock on demand. | ||
1167 | * 2. UDC VBUS detect: we have to enable clock all the time. | ||
1168 | * 3. No VBUS detect: we have to enable clock all the time. | ||
1169 | */ | ||
1170 | if (u3d->driver && u3d->softconnect && u3d->vbus_active) { | ||
1171 | retval = mv_u3d_enable(u3d); | ||
1172 | if (retval == 0) { | ||
1173 | /* | ||
1174 | * after clock is disabled, we lost all the register | ||
1175 | * context. We have to re-init registers | ||
1176 | */ | ||
1177 | mv_u3d_controller_reset(u3d); | ||
1178 | mv_u3d_ep0_reset(u3d); | ||
1179 | mv_u3d_controller_start(u3d); | ||
1180 | } | ||
1181 | } else if (u3d->driver && u3d->softconnect) { | ||
1182 | if (!u3d->active) | ||
1183 | goto out; | ||
1184 | |||
1185 | /* stop all the transfer in queue*/ | ||
1186 | mv_u3d_stop_activity(u3d, u3d->driver); | ||
1187 | mv_u3d_controller_stop(u3d); | ||
1188 | mv_u3d_disable(u3d); | ||
1189 | } | ||
1190 | |||
1191 | out: | ||
1192 | spin_unlock_irqrestore(&u3d->lock, flags); | ||
1193 | return retval; | ||
1194 | } | ||
1195 | |||
1196 | /* constrain controller's VBUS power usage | ||
1197 | * This call is used by gadget drivers during SET_CONFIGURATION calls, | ||
1198 | * reporting how much power the device may consume. For example, this | ||
1199 | * could affect how quickly batteries are recharged. | ||
1200 | * | ||
1201 | * Returns zero on success, else negative errno. | ||
1202 | */ | ||
1203 | static int mv_u3d_vbus_draw(struct usb_gadget *gadget, unsigned mA) | ||
1204 | { | ||
1205 | struct mv_u3d *u3d = container_of(gadget, struct mv_u3d, gadget); | ||
1206 | |||
1207 | u3d->power = mA; | ||
1208 | |||
1209 | return 0; | ||
1210 | } | ||
1211 | |||
1212 | static int mv_u3d_pullup(struct usb_gadget *gadget, int is_on) | ||
1213 | { | ||
1214 | struct mv_u3d *u3d = container_of(gadget, struct mv_u3d, gadget); | ||
1215 | unsigned long flags; | ||
1216 | int retval = 0; | ||
1217 | |||
1218 | spin_lock_irqsave(&u3d->lock, flags); | ||
1219 | |||
1220 | dev_dbg(u3d->dev, "%s: softconnect %d, vbus_active %d\n", | ||
1221 | __func__, u3d->softconnect, u3d->vbus_active); | ||
1222 | u3d->softconnect = (is_on != 0); | ||
1223 | if (u3d->driver && u3d->softconnect && u3d->vbus_active) { | ||
1224 | retval = mv_u3d_enable(u3d); | ||
1225 | if (retval == 0) { | ||
1226 | /* | ||
1227 | * after clock is disabled, we lost all the register | ||
1228 | * context. We have to re-init registers | ||
1229 | */ | ||
1230 | mv_u3d_controller_reset(u3d); | ||
1231 | mv_u3d_ep0_reset(u3d); | ||
1232 | mv_u3d_controller_start(u3d); | ||
1233 | } | ||
1234 | } else if (u3d->driver && u3d->vbus_active) { | ||
1235 | /* stop all the transfer in queue*/ | ||
1236 | mv_u3d_stop_activity(u3d, u3d->driver); | ||
1237 | mv_u3d_controller_stop(u3d); | ||
1238 | mv_u3d_disable(u3d); | ||
1239 | } | ||
1240 | |||
1241 | spin_unlock_irqrestore(&u3d->lock, flags); | ||
1242 | |||
1243 | return retval; | ||
1244 | } | ||
1245 | |||
1246 | static int mv_u3d_start(struct usb_gadget *g, | ||
1247 | struct usb_gadget_driver *driver) | ||
1248 | { | ||
1249 | struct mv_u3d *u3d = container_of(g, struct mv_u3d, gadget); | ||
1250 | struct mv_usb_platform_data *pdata = u3d->dev->platform_data; | ||
1251 | unsigned long flags; | ||
1252 | |||
1253 | if (u3d->driver) | ||
1254 | return -EBUSY; | ||
1255 | |||
1256 | spin_lock_irqsave(&u3d->lock, flags); | ||
1257 | |||
1258 | if (!u3d->clock_gating) { | ||
1259 | clk_enable(u3d->clk); | ||
1260 | if (pdata->phy_init) | ||
1261 | pdata->phy_init(u3d->phy_regs); | ||
1262 | } | ||
1263 | |||
1264 | /* hook up the driver ... */ | ||
1265 | driver->driver.bus = NULL; | ||
1266 | u3d->driver = driver; | ||
1267 | u3d->gadget.dev.driver = &driver->driver; | ||
1268 | |||
1269 | u3d->ep0_dir = USB_DIR_OUT; | ||
1270 | |||
1271 | spin_unlock_irqrestore(&u3d->lock, flags); | ||
1272 | |||
1273 | u3d->vbus_valid_detect = 1; | ||
1274 | |||
1275 | return 0; | ||
1276 | } | ||
1277 | |||
1278 | static int mv_u3d_stop(struct usb_gadget *g, | ||
1279 | struct usb_gadget_driver *driver) | ||
1280 | { | ||
1281 | struct mv_u3d *u3d = container_of(g, struct mv_u3d, gadget); | ||
1282 | struct mv_usb_platform_data *pdata = u3d->dev->platform_data; | ||
1283 | unsigned long flags; | ||
1284 | |||
1285 | u3d->vbus_valid_detect = 0; | ||
1286 | spin_lock_irqsave(&u3d->lock, flags); | ||
1287 | |||
1288 | /* enable clock to access controller register */ | ||
1289 | clk_enable(u3d->clk); | ||
1290 | if (pdata->phy_init) | ||
1291 | pdata->phy_init(u3d->phy_regs); | ||
1292 | |||
1293 | mv_u3d_controller_stop(u3d); | ||
1294 | /* stop all usb activities */ | ||
1295 | u3d->gadget.speed = USB_SPEED_UNKNOWN; | ||
1296 | mv_u3d_stop_activity(u3d, driver); | ||
1297 | mv_u3d_disable(u3d); | ||
1298 | |||
1299 | if (pdata->phy_deinit) | ||
1300 | pdata->phy_deinit(u3d->phy_regs); | ||
1301 | clk_disable(u3d->clk); | ||
1302 | |||
1303 | spin_unlock_irqrestore(&u3d->lock, flags); | ||
1304 | |||
1305 | u3d->gadget.dev.driver = NULL; | ||
1306 | u3d->driver = NULL; | ||
1307 | |||
1308 | return 0; | ||
1309 | } | ||
1310 | |||
1311 | /* device controller usb_gadget_ops structure */ | ||
1312 | static const struct usb_gadget_ops mv_u3d_ops = { | ||
1313 | /* notify controller that VBUS is powered or not */ | ||
1314 | .vbus_session = mv_u3d_vbus_session, | ||
1315 | |||
1316 | /* constrain controller's VBUS power usage */ | ||
1317 | .vbus_draw = mv_u3d_vbus_draw, | ||
1318 | |||
1319 | .pullup = mv_u3d_pullup, | ||
1320 | .udc_start = mv_u3d_start, | ||
1321 | .udc_stop = mv_u3d_stop, | ||
1322 | }; | ||
1323 | |||
1324 | static int mv_u3d_eps_init(struct mv_u3d *u3d) | ||
1325 | { | ||
1326 | struct mv_u3d_ep *ep; | ||
1327 | char name[14]; | ||
1328 | int i; | ||
1329 | |||
1330 | /* initialize ep0, ep0 in/out use eps[1] */ | ||
1331 | ep = &u3d->eps[1]; | ||
1332 | ep->u3d = u3d; | ||
1333 | strncpy(ep->name, "ep0", sizeof(ep->name)); | ||
1334 | ep->ep.name = ep->name; | ||
1335 | ep->ep.ops = &mv_u3d_ep_ops; | ||
1336 | ep->wedge = 0; | ||
1337 | ep->ep.maxpacket = MV_U3D_EP0_MAX_PKT_SIZE; | ||
1338 | ep->ep_num = 0; | ||
1339 | ep->ep.desc = &mv_u3d_ep0_desc; | ||
1340 | INIT_LIST_HEAD(&ep->queue); | ||
1341 | INIT_LIST_HEAD(&ep->req_list); | ||
1342 | ep->ep_type = USB_ENDPOINT_XFER_CONTROL; | ||
1343 | |||
1344 | /* add ep0 ep_context */ | ||
1345 | ep->ep_context = &u3d->ep_context[1]; | ||
1346 | |||
1347 | /* initialize other endpoints */ | ||
1348 | for (i = 2; i < u3d->max_eps * 2; i++) { | ||
1349 | ep = &u3d->eps[i]; | ||
1350 | if (i & 1) { | ||
1351 | snprintf(name, sizeof(name), "ep%din", i >> 1); | ||
1352 | ep->direction = MV_U3D_EP_DIR_IN; | ||
1353 | } else { | ||
1354 | snprintf(name, sizeof(name), "ep%dout", i >> 1); | ||
1355 | ep->direction = MV_U3D_EP_DIR_OUT; | ||
1356 | } | ||
1357 | ep->u3d = u3d; | ||
1358 | strncpy(ep->name, name, sizeof(ep->name)); | ||
1359 | ep->ep.name = ep->name; | ||
1360 | |||
1361 | ep->ep.ops = &mv_u3d_ep_ops; | ||
1362 | ep->ep.maxpacket = (unsigned short) ~0; | ||
1363 | ep->ep_num = i / 2; | ||
1364 | |||
1365 | INIT_LIST_HEAD(&ep->queue); | ||
1366 | list_add_tail(&ep->ep.ep_list, &u3d->gadget.ep_list); | ||
1367 | |||
1368 | INIT_LIST_HEAD(&ep->req_list); | ||
1369 | spin_lock_init(&ep->req_lock); | ||
1370 | ep->ep_context = &u3d->ep_context[i]; | ||
1371 | } | ||
1372 | |||
1373 | return 0; | ||
1374 | } | ||
1375 | |||
1376 | /* delete all endpoint requests, called with spinlock held */ | ||
1377 | static void mv_u3d_nuke(struct mv_u3d_ep *ep, int status) | ||
1378 | { | ||
1379 | /* endpoint fifo flush */ | ||
1380 | mv_u3d_ep_fifo_flush(&ep->ep); | ||
1381 | |||
1382 | while (!list_empty(&ep->queue)) { | ||
1383 | struct mv_u3d_req *req = NULL; | ||
1384 | req = list_entry(ep->queue.next, struct mv_u3d_req, queue); | ||
1385 | mv_u3d_done(ep, req, status); | ||
1386 | } | ||
1387 | } | ||
1388 | |||
1389 | /* stop all USB activities */ | ||
1390 | static | ||
1391 | void mv_u3d_stop_activity(struct mv_u3d *u3d, struct usb_gadget_driver *driver) | ||
1392 | { | ||
1393 | struct mv_u3d_ep *ep; | ||
1394 | |||
1395 | mv_u3d_nuke(&u3d->eps[1], -ESHUTDOWN); | ||
1396 | |||
1397 | list_for_each_entry(ep, &u3d->gadget.ep_list, ep.ep_list) { | ||
1398 | mv_u3d_nuke(ep, -ESHUTDOWN); | ||
1399 | } | ||
1400 | |||
1401 | /* report disconnect; the driver is already quiesced */ | ||
1402 | if (driver) { | ||
1403 | spin_unlock(&u3d->lock); | ||
1404 | driver->disconnect(&u3d->gadget); | ||
1405 | spin_lock(&u3d->lock); | ||
1406 | } | ||
1407 | } | ||
1408 | |||
1409 | static void mv_u3d_irq_process_error(struct mv_u3d *u3d) | ||
1410 | { | ||
1411 | /* Increment the error count */ | ||
1412 | u3d->errors++; | ||
1413 | dev_err(u3d->dev, "%s\n", __func__); | ||
1414 | } | ||
1415 | |||
1416 | static void mv_u3d_irq_process_link_change(struct mv_u3d *u3d) | ||
1417 | { | ||
1418 | u32 linkchange; | ||
1419 | |||
1420 | linkchange = ioread32(&u3d->vuc_regs->linkchange); | ||
1421 | iowrite32(linkchange, &u3d->vuc_regs->linkchange); | ||
1422 | |||
1423 | dev_dbg(u3d->dev, "linkchange: 0x%x\n", linkchange); | ||
1424 | |||
1425 | if (linkchange & MV_U3D_LINK_CHANGE_LINK_UP) { | ||
1426 | dev_dbg(u3d->dev, "link up: ltssm state: 0x%x\n", | ||
1427 | ioread32(&u3d->vuc_regs->ltssmstate)); | ||
1428 | |||
1429 | u3d->usb_state = USB_STATE_DEFAULT; | ||
1430 | u3d->ep0_dir = MV_U3D_EP_DIR_OUT; | ||
1431 | u3d->ep0_state = MV_U3D_WAIT_FOR_SETUP; | ||
1432 | |||
1433 | /* set speed */ | ||
1434 | u3d->gadget.speed = USB_SPEED_SUPER; | ||
1435 | } | ||
1436 | |||
1437 | if (linkchange & MV_U3D_LINK_CHANGE_SUSPEND) { | ||
1438 | dev_dbg(u3d->dev, "link suspend\n"); | ||
1439 | u3d->resume_state = u3d->usb_state; | ||
1440 | u3d->usb_state = USB_STATE_SUSPENDED; | ||
1441 | } | ||
1442 | |||
1443 | if (linkchange & MV_U3D_LINK_CHANGE_RESUME) { | ||
1444 | dev_dbg(u3d->dev, "link resume\n"); | ||
1445 | u3d->usb_state = u3d->resume_state; | ||
1446 | u3d->resume_state = 0; | ||
1447 | } | ||
1448 | |||
1449 | if (linkchange & MV_U3D_LINK_CHANGE_WRESET) { | ||
1450 | dev_dbg(u3d->dev, "warm reset\n"); | ||
1451 | u3d->usb_state = USB_STATE_POWERED; | ||
1452 | } | ||
1453 | |||
1454 | if (linkchange & MV_U3D_LINK_CHANGE_HRESET) { | ||
1455 | dev_dbg(u3d->dev, "hot reset\n"); | ||
1456 | u3d->usb_state = USB_STATE_DEFAULT; | ||
1457 | } | ||
1458 | |||
1459 | if (linkchange & MV_U3D_LINK_CHANGE_INACT) | ||
1460 | dev_dbg(u3d->dev, "inactive\n"); | ||
1461 | |||
1462 | if (linkchange & MV_U3D_LINK_CHANGE_DISABLE_AFTER_U0) | ||
1463 | dev_dbg(u3d->dev, "ss.disabled\n"); | ||
1464 | |||
1465 | if (linkchange & MV_U3D_LINK_CHANGE_VBUS_INVALID) { | ||
1466 | dev_dbg(u3d->dev, "vbus invalid\n"); | ||
1467 | u3d->usb_state = USB_STATE_ATTACHED; | ||
1468 | u3d->vbus_valid_detect = 1; | ||
1469 | /* if external vbus detect is not supported, | ||
1470 | * we handle it here. | ||
1471 | */ | ||
1472 | if (!u3d->vbus) { | ||
1473 | spin_unlock(&u3d->lock); | ||
1474 | mv_u3d_vbus_session(&u3d->gadget, 0); | ||
1475 | spin_lock(&u3d->lock); | ||
1476 | } | ||
1477 | } | ||
1478 | } | ||
1479 | |||
1480 | static void mv_u3d_ch9setaddress(struct mv_u3d *u3d, | ||
1481 | struct usb_ctrlrequest *setup) | ||
1482 | { | ||
1483 | u32 tmp; | ||
1484 | |||
1485 | if (u3d->usb_state != USB_STATE_DEFAULT) { | ||
1486 | dev_err(u3d->dev, | ||
1487 | "%s, cannot setaddr in this state (%d)\n", | ||
1488 | __func__, u3d->usb_state); | ||
1489 | goto err; | ||
1490 | } | ||
1491 | |||
1492 | u3d->dev_addr = (u8)setup->wValue; | ||
1493 | |||
1494 | dev_dbg(u3d->dev, "%s: 0x%x\n", __func__, u3d->dev_addr); | ||
1495 | |||
1496 | if (u3d->dev_addr > 127) { | ||
1497 | dev_err(u3d->dev, | ||
1498 | "%s, u3d address is wrong (out of range)\n", __func__); | ||
1499 | u3d->dev_addr = 0; | ||
1500 | goto err; | ||
1501 | } | ||
1502 | |||
1503 | /* update usb state */ | ||
1504 | u3d->usb_state = USB_STATE_ADDRESS; | ||
1505 | |||
1506 | /* set the new address */ | ||
1507 | tmp = ioread32(&u3d->vuc_regs->devaddrtiebrkr); | ||
1508 | tmp &= ~0x7F; | ||
1509 | tmp |= (u32)u3d->dev_addr; | ||
1510 | iowrite32(tmp, &u3d->vuc_regs->devaddrtiebrkr); | ||
1511 | |||
1512 | return; | ||
1513 | err: | ||
1514 | mv_u3d_ep0_stall(u3d); | ||
1515 | } | ||
1516 | |||
1517 | static int mv_u3d_is_set_configuration(struct usb_ctrlrequest *setup) | ||
1518 | { | ||
1519 | if ((setup->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) | ||
1520 | if (setup->bRequest == USB_REQ_SET_CONFIGURATION) | ||
1521 | return 1; | ||
1522 | |||
1523 | return 0; | ||
1524 | } | ||
1525 | |||
1526 | static void mv_u3d_handle_setup_packet(struct mv_u3d *u3d, u8 ep_num, | ||
1527 | struct usb_ctrlrequest *setup) | ||
1528 | { | ||
1529 | bool delegate = false; | ||
1530 | |||
1531 | mv_u3d_nuke(&u3d->eps[ep_num * 2 + MV_U3D_EP_DIR_IN], -ESHUTDOWN); | ||
1532 | |||
1533 | dev_dbg(u3d->dev, "SETUP %02x.%02x v%04x i%04x l%04x\n", | ||
1534 | setup->bRequestType, setup->bRequest, | ||
1535 | setup->wValue, setup->wIndex, setup->wLength); | ||
1536 | |||
1537 | /* We process some stardard setup requests here */ | ||
1538 | if ((setup->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | ||
1539 | switch (setup->bRequest) { | ||
1540 | case USB_REQ_GET_STATUS: | ||
1541 | delegate = true; | ||
1542 | break; | ||
1543 | |||
1544 | case USB_REQ_SET_ADDRESS: | ||
1545 | mv_u3d_ch9setaddress(u3d, setup); | ||
1546 | break; | ||
1547 | |||
1548 | case USB_REQ_CLEAR_FEATURE: | ||
1549 | delegate = true; | ||
1550 | break; | ||
1551 | |||
1552 | case USB_REQ_SET_FEATURE: | ||
1553 | delegate = true; | ||
1554 | break; | ||
1555 | |||
1556 | default: | ||
1557 | delegate = true; | ||
1558 | } | ||
1559 | } else | ||
1560 | delegate = true; | ||
1561 | |||
1562 | /* delegate USB standard requests to the gadget driver */ | ||
1563 | if (delegate == true) { | ||
1564 | /* USB requests handled by gadget */ | ||
1565 | if (setup->wLength) { | ||
1566 | /* DATA phase from gadget, STATUS phase from u3d */ | ||
1567 | u3d->ep0_dir = (setup->bRequestType & USB_DIR_IN) | ||
1568 | ? MV_U3D_EP_DIR_IN : MV_U3D_EP_DIR_OUT; | ||
1569 | spin_unlock(&u3d->lock); | ||
1570 | if (u3d->driver->setup(&u3d->gadget, | ||
1571 | &u3d->local_setup_buff) < 0) { | ||
1572 | dev_err(u3d->dev, "setup error!\n"); | ||
1573 | mv_u3d_ep0_stall(u3d); | ||
1574 | } | ||
1575 | spin_lock(&u3d->lock); | ||
1576 | } else { | ||
1577 | /* no DATA phase, STATUS phase from gadget */ | ||
1578 | u3d->ep0_dir = MV_U3D_EP_DIR_IN; | ||
1579 | u3d->ep0_state = MV_U3D_STATUS_STAGE; | ||
1580 | spin_unlock(&u3d->lock); | ||
1581 | if (u3d->driver->setup(&u3d->gadget, | ||
1582 | &u3d->local_setup_buff) < 0) | ||
1583 | mv_u3d_ep0_stall(u3d); | ||
1584 | spin_lock(&u3d->lock); | ||
1585 | } | ||
1586 | |||
1587 | if (mv_u3d_is_set_configuration(setup)) { | ||
1588 | dev_dbg(u3d->dev, "u3d configured\n"); | ||
1589 | u3d->usb_state = USB_STATE_CONFIGURED; | ||
1590 | } | ||
1591 | } | ||
1592 | } | ||
1593 | |||
1594 | static void mv_u3d_get_setup_data(struct mv_u3d *u3d, u8 ep_num, u8 *buffer_ptr) | ||
1595 | { | ||
1596 | struct mv_u3d_ep_context *epcontext; | ||
1597 | |||
1598 | epcontext = &u3d->ep_context[ep_num * 2 + MV_U3D_EP_DIR_IN]; | ||
1599 | |||
1600 | /* Copy the setup packet to local buffer */ | ||
1601 | memcpy(buffer_ptr, (u8 *) &epcontext->setup_buffer, 8); | ||
1602 | } | ||
1603 | |||
1604 | static void mv_u3d_irq_process_setup(struct mv_u3d *u3d) | ||
1605 | { | ||
1606 | u32 tmp, i; | ||
1607 | /* Process all Setup packet received interrupts */ | ||
1608 | tmp = ioread32(&u3d->vuc_regs->setuplock); | ||
1609 | if (tmp) { | ||
1610 | for (i = 0; i < u3d->max_eps; i++) { | ||
1611 | if (tmp & (1 << i)) { | ||
1612 | mv_u3d_get_setup_data(u3d, i, | ||
1613 | (u8 *)(&u3d->local_setup_buff)); | ||
1614 | mv_u3d_handle_setup_packet(u3d, i, | ||
1615 | &u3d->local_setup_buff); | ||
1616 | } | ||
1617 | } | ||
1618 | } | ||
1619 | |||
1620 | iowrite32(tmp, &u3d->vuc_regs->setuplock); | ||
1621 | } | ||
1622 | |||
1623 | static void mv_u3d_irq_process_tr_complete(struct mv_u3d *u3d) | ||
1624 | { | ||
1625 | u32 tmp, bit_pos; | ||
1626 | int i, ep_num = 0, direction = 0; | ||
1627 | struct mv_u3d_ep *curr_ep; | ||
1628 | struct mv_u3d_req *curr_req, *temp_req; | ||
1629 | int status; | ||
1630 | |||
1631 | tmp = ioread32(&u3d->vuc_regs->endcomplete); | ||
1632 | |||
1633 | dev_dbg(u3d->dev, "tr_complete: ep: 0x%x\n", tmp); | ||
1634 | if (!tmp) | ||
1635 | return; | ||
1636 | iowrite32(tmp, &u3d->vuc_regs->endcomplete); | ||
1637 | |||
1638 | for (i = 0; i < u3d->max_eps * 2; i++) { | ||
1639 | ep_num = i >> 1; | ||
1640 | direction = i % 2; | ||
1641 | |||
1642 | bit_pos = 1 << (ep_num + 16 * direction); | ||
1643 | |||
1644 | if (!(bit_pos & tmp)) | ||
1645 | continue; | ||
1646 | |||
1647 | if (i == 0) | ||
1648 | curr_ep = &u3d->eps[1]; | ||
1649 | else | ||
1650 | curr_ep = &u3d->eps[i]; | ||
1651 | |||
1652 | /* remove req out of ep request list after completion */ | ||
1653 | dev_dbg(u3d->dev, "tr comp: check req_list\n"); | ||
1654 | spin_lock(&curr_ep->req_lock); | ||
1655 | if (!list_empty(&curr_ep->req_list)) { | ||
1656 | struct mv_u3d_req *req; | ||
1657 | req = list_entry(curr_ep->req_list.next, | ||
1658 | struct mv_u3d_req, list); | ||
1659 | list_del_init(&req->list); | ||
1660 | curr_ep->processing = 0; | ||
1661 | } | ||
1662 | spin_unlock(&curr_ep->req_lock); | ||
1663 | |||
1664 | /* process the req queue until an uncomplete request */ | ||
1665 | list_for_each_entry_safe(curr_req, temp_req, | ||
1666 | &curr_ep->queue, queue) { | ||
1667 | status = mv_u3d_process_ep_req(u3d, i, curr_req); | ||
1668 | if (status) | ||
1669 | break; | ||
1670 | /* write back status to req */ | ||
1671 | curr_req->req.status = status; | ||
1672 | |||
1673 | /* ep0 request completion */ | ||
1674 | if (ep_num == 0) { | ||
1675 | mv_u3d_done(curr_ep, curr_req, 0); | ||
1676 | break; | ||
1677 | } else { | ||
1678 | mv_u3d_done(curr_ep, curr_req, status); | ||
1679 | } | ||
1680 | } | ||
1681 | |||
1682 | dev_dbg(u3d->dev, "call mv_u3d_start_queue from ep complete\n"); | ||
1683 | mv_u3d_start_queue(curr_ep); | ||
1684 | } | ||
1685 | } | ||
1686 | |||
1687 | static irqreturn_t mv_u3d_irq(int irq, void *dev) | ||
1688 | { | ||
1689 | struct mv_u3d *u3d = (struct mv_u3d *)dev; | ||
1690 | u32 status, intr; | ||
1691 | u32 bridgesetting; | ||
1692 | u32 trbunderrun; | ||
1693 | |||
1694 | spin_lock(&u3d->lock); | ||
1695 | |||
1696 | status = ioread32(&u3d->vuc_regs->intrcause); | ||
1697 | intr = ioread32(&u3d->vuc_regs->intrenable); | ||
1698 | status &= intr; | ||
1699 | |||
1700 | if (status == 0) { | ||
1701 | spin_unlock(&u3d->lock); | ||
1702 | dev_err(u3d->dev, "irq error!\n"); | ||
1703 | return IRQ_NONE; | ||
1704 | } | ||
1705 | |||
1706 | if (status & MV_U3D_USBINT_VBUS_VALID) { | ||
1707 | bridgesetting = ioread32(&u3d->vuc_regs->bridgesetting); | ||
1708 | if (bridgesetting & MV_U3D_BRIDGE_SETTING_VBUS_VALID) { | ||
1709 | /* write vbus valid bit of bridge setting to clear */ | ||
1710 | bridgesetting = MV_U3D_BRIDGE_SETTING_VBUS_VALID; | ||
1711 | iowrite32(bridgesetting, &u3d->vuc_regs->bridgesetting); | ||
1712 | dev_dbg(u3d->dev, "vbus valid\n"); | ||
1713 | |||
1714 | u3d->usb_state = USB_STATE_POWERED; | ||
1715 | u3d->vbus_valid_detect = 0; | ||
1716 | /* if external vbus detect is not supported, | ||
1717 | * we handle it here. | ||
1718 | */ | ||
1719 | if (!u3d->vbus) { | ||
1720 | spin_unlock(&u3d->lock); | ||
1721 | mv_u3d_vbus_session(&u3d->gadget, 1); | ||
1722 | spin_lock(&u3d->lock); | ||
1723 | } | ||
1724 | } else | ||
1725 | dev_err(u3d->dev, "vbus bit is not set\n"); | ||
1726 | } | ||
1727 | |||
1728 | /* RX data is already in the 16KB FIFO.*/ | ||
1729 | if (status & MV_U3D_USBINT_UNDER_RUN) { | ||
1730 | trbunderrun = ioread32(&u3d->vuc_regs->trbunderrun); | ||
1731 | dev_err(u3d->dev, "under run, ep%d\n", trbunderrun); | ||
1732 | iowrite32(trbunderrun, &u3d->vuc_regs->trbunderrun); | ||
1733 | mv_u3d_irq_process_error(u3d); | ||
1734 | } | ||
1735 | |||
1736 | if (status & (MV_U3D_USBINT_RXDESC_ERR | MV_U3D_USBINT_TXDESC_ERR)) { | ||
1737 | /* write one to clear */ | ||
1738 | iowrite32(status & (MV_U3D_USBINT_RXDESC_ERR | ||
1739 | | MV_U3D_USBINT_TXDESC_ERR), | ||
1740 | &u3d->vuc_regs->intrcause); | ||
1741 | dev_err(u3d->dev, "desc err 0x%x\n", status); | ||
1742 | mv_u3d_irq_process_error(u3d); | ||
1743 | } | ||
1744 | |||
1745 | if (status & MV_U3D_USBINT_LINK_CHG) | ||
1746 | mv_u3d_irq_process_link_change(u3d); | ||
1747 | |||
1748 | if (status & MV_U3D_USBINT_TX_COMPLETE) | ||
1749 | mv_u3d_irq_process_tr_complete(u3d); | ||
1750 | |||
1751 | if (status & MV_U3D_USBINT_RX_COMPLETE) | ||
1752 | mv_u3d_irq_process_tr_complete(u3d); | ||
1753 | |||
1754 | if (status & MV_U3D_USBINT_SETUP) | ||
1755 | mv_u3d_irq_process_setup(u3d); | ||
1756 | |||
1757 | spin_unlock(&u3d->lock); | ||
1758 | return IRQ_HANDLED; | ||
1759 | } | ||
1760 | |||
1761 | static void mv_u3d_gadget_release(struct device *dev) | ||
1762 | { | ||
1763 | dev_dbg(dev, "%s\n", __func__); | ||
1764 | } | ||
1765 | |||
1766 | static __devexit int mv_u3d_remove(struct platform_device *dev) | ||
1767 | { | ||
1768 | struct mv_u3d *u3d = platform_get_drvdata(dev); | ||
1769 | |||
1770 | BUG_ON(u3d == NULL); | ||
1771 | |||
1772 | usb_del_gadget_udc(&u3d->gadget); | ||
1773 | |||
1774 | /* free memory allocated in probe */ | ||
1775 | if (u3d->trb_pool) | ||
1776 | dma_pool_destroy(u3d->trb_pool); | ||
1777 | |||
1778 | if (u3d->ep_context) | ||
1779 | dma_free_coherent(&dev->dev, u3d->ep_context_size, | ||
1780 | u3d->ep_context, u3d->ep_context_dma); | ||
1781 | |||
1782 | kfree(u3d->eps); | ||
1783 | |||
1784 | if (u3d->irq) | ||
1785 | free_irq(u3d->irq, &dev->dev); | ||
1786 | |||
1787 | if (u3d->cap_regs) | ||
1788 | iounmap(u3d->cap_regs); | ||
1789 | u3d->cap_regs = NULL; | ||
1790 | |||
1791 | kfree(u3d->status_req); | ||
1792 | |||
1793 | clk_put(u3d->clk); | ||
1794 | |||
1795 | device_unregister(&u3d->gadget.dev); | ||
1796 | |||
1797 | platform_set_drvdata(dev, NULL); | ||
1798 | |||
1799 | kfree(u3d); | ||
1800 | |||
1801 | return 0; | ||
1802 | } | ||
1803 | |||
1804 | static int mv_u3d_probe(struct platform_device *dev) | ||
1805 | { | ||
1806 | struct mv_u3d *u3d = NULL; | ||
1807 | struct mv_usb_platform_data *pdata = dev->dev.platform_data; | ||
1808 | int retval = 0; | ||
1809 | struct resource *r; | ||
1810 | size_t size; | ||
1811 | |||
1812 | if (!dev->dev.platform_data) { | ||
1813 | dev_err(&dev->dev, "missing platform_data\n"); | ||
1814 | retval = -ENODEV; | ||
1815 | goto err_pdata; | ||
1816 | } | ||
1817 | |||
1818 | u3d = kzalloc(sizeof(*u3d), GFP_KERNEL); | ||
1819 | if (!u3d) { | ||
1820 | dev_err(&dev->dev, "failed to allocate memory for u3d\n"); | ||
1821 | retval = -ENOMEM; | ||
1822 | goto err_alloc_private; | ||
1823 | } | ||
1824 | |||
1825 | spin_lock_init(&u3d->lock); | ||
1826 | |||
1827 | platform_set_drvdata(dev, u3d); | ||
1828 | |||
1829 | u3d->dev = &dev->dev; | ||
1830 | u3d->vbus = pdata->vbus; | ||
1831 | |||
1832 | u3d->clk = clk_get(&dev->dev, pdata->clkname[0]); | ||
1833 | if (IS_ERR(u3d->clk)) { | ||
1834 | retval = PTR_ERR(u3d->clk); | ||
1835 | goto err_get_clk; | ||
1836 | } | ||
1837 | |||
1838 | r = platform_get_resource_byname(dev, IORESOURCE_MEM, "capregs"); | ||
1839 | if (!r) { | ||
1840 | dev_err(&dev->dev, "no I/O memory resource defined\n"); | ||
1841 | retval = -ENODEV; | ||
1842 | goto err_get_cap_regs; | ||
1843 | } | ||
1844 | |||
1845 | u3d->cap_regs = (struct mv_u3d_cap_regs __iomem *) | ||
1846 | ioremap(r->start, resource_size(r)); | ||
1847 | if (!u3d->cap_regs) { | ||
1848 | dev_err(&dev->dev, "failed to map I/O memory\n"); | ||
1849 | retval = -EBUSY; | ||
1850 | goto err_map_cap_regs; | ||
1851 | } else { | ||
1852 | dev_dbg(&dev->dev, "cap_regs address: 0x%x/0x%x\n", | ||
1853 | (unsigned int)r->start, (unsigned int)u3d->cap_regs); | ||
1854 | } | ||
1855 | |||
1856 | /* we will access controller register, so enable the u3d controller */ | ||
1857 | clk_enable(u3d->clk); | ||
1858 | |||
1859 | if (pdata->phy_init) { | ||
1860 | retval = pdata->phy_init(u3d->phy_regs); | ||
1861 | if (retval) { | ||
1862 | dev_err(&dev->dev, "init phy error %d\n", retval); | ||
1863 | goto err_u3d_enable; | ||
1864 | } | ||
1865 | } | ||
1866 | |||
1867 | u3d->op_regs = (struct mv_u3d_op_regs __iomem *)((u32)u3d->cap_regs | ||
1868 | + MV_U3D_USB3_OP_REGS_OFFSET); | ||
1869 | |||
1870 | u3d->vuc_regs = (struct mv_u3d_vuc_regs __iomem *)((u32)u3d->cap_regs | ||
1871 | + ioread32(&u3d->cap_regs->vuoff)); | ||
1872 | |||
1873 | u3d->max_eps = 16; | ||
1874 | |||
1875 | /* | ||
1876 | * some platform will use usb to download image, it may not disconnect | ||
1877 | * usb gadget before loading kernel. So first stop u3d here. | ||
1878 | */ | ||
1879 | mv_u3d_controller_stop(u3d); | ||
1880 | iowrite32(0xFFFFFFFF, &u3d->vuc_regs->intrcause); | ||
1881 | |||
1882 | if (pdata->phy_deinit) | ||
1883 | pdata->phy_deinit(u3d->phy_regs); | ||
1884 | clk_disable(u3d->clk); | ||
1885 | |||
1886 | size = u3d->max_eps * sizeof(struct mv_u3d_ep_context) * 2; | ||
1887 | size = (size + MV_U3D_EP_CONTEXT_ALIGNMENT - 1) | ||
1888 | & ~(MV_U3D_EP_CONTEXT_ALIGNMENT - 1); | ||
1889 | u3d->ep_context = dma_alloc_coherent(&dev->dev, size, | ||
1890 | &u3d->ep_context_dma, GFP_KERNEL); | ||
1891 | if (!u3d->ep_context) { | ||
1892 | dev_err(&dev->dev, "allocate ep context memory failed\n"); | ||
1893 | retval = -ENOMEM; | ||
1894 | goto err_alloc_ep_context; | ||
1895 | } | ||
1896 | u3d->ep_context_size = size; | ||
1897 | |||
1898 | /* create TRB dma_pool resource */ | ||
1899 | u3d->trb_pool = dma_pool_create("u3d_trb", | ||
1900 | &dev->dev, | ||
1901 | sizeof(struct mv_u3d_trb_hw), | ||
1902 | MV_U3D_TRB_ALIGNMENT, | ||
1903 | MV_U3D_DMA_BOUNDARY); | ||
1904 | |||
1905 | if (!u3d->trb_pool) { | ||
1906 | retval = -ENOMEM; | ||
1907 | goto err_alloc_trb_pool; | ||
1908 | } | ||
1909 | |||
1910 | size = u3d->max_eps * sizeof(struct mv_u3d_ep) * 2; | ||
1911 | u3d->eps = kzalloc(size, GFP_KERNEL); | ||
1912 | if (!u3d->eps) { | ||
1913 | dev_err(&dev->dev, "allocate ep memory failed\n"); | ||
1914 | retval = -ENOMEM; | ||
1915 | goto err_alloc_eps; | ||
1916 | } | ||
1917 | |||
1918 | /* initialize ep0 status request structure */ | ||
1919 | u3d->status_req = kzalloc(sizeof(struct mv_u3d_req) + 8, GFP_KERNEL); | ||
1920 | if (!u3d->status_req) { | ||
1921 | dev_err(&dev->dev, "allocate status_req memory failed\n"); | ||
1922 | retval = -ENOMEM; | ||
1923 | goto err_alloc_status_req; | ||
1924 | } | ||
1925 | INIT_LIST_HEAD(&u3d->status_req->queue); | ||
1926 | |||
1927 | /* allocate a small amount of memory to get valid address */ | ||
1928 | u3d->status_req->req.buf = (char *)u3d->status_req | ||
1929 | + sizeof(struct mv_u3d_req); | ||
1930 | u3d->status_req->req.dma = virt_to_phys(u3d->status_req->req.buf); | ||
1931 | |||
1932 | u3d->resume_state = USB_STATE_NOTATTACHED; | ||
1933 | u3d->usb_state = USB_STATE_ATTACHED; | ||
1934 | u3d->ep0_dir = MV_U3D_EP_DIR_OUT; | ||
1935 | u3d->remote_wakeup = 0; | ||
1936 | |||
1937 | r = platform_get_resource(dev, IORESOURCE_IRQ, 0); | ||
1938 | if (!r) { | ||
1939 | dev_err(&dev->dev, "no IRQ resource defined\n"); | ||
1940 | retval = -ENODEV; | ||
1941 | goto err_get_irq; | ||
1942 | } | ||
1943 | u3d->irq = r->start; | ||
1944 | if (request_irq(u3d->irq, mv_u3d_irq, | ||
1945 | IRQF_DISABLED | IRQF_SHARED, driver_name, u3d)) { | ||
1946 | u3d->irq = 0; | ||
1947 | dev_err(&dev->dev, "Request irq %d for u3d failed\n", | ||
1948 | u3d->irq); | ||
1949 | retval = -ENODEV; | ||
1950 | goto err_request_irq; | ||
1951 | } | ||
1952 | |||
1953 | /* initialize gadget structure */ | ||
1954 | u3d->gadget.ops = &mv_u3d_ops; /* usb_gadget_ops */ | ||
1955 | u3d->gadget.ep0 = &u3d->eps[1].ep; /* gadget ep0 */ | ||
1956 | INIT_LIST_HEAD(&u3d->gadget.ep_list); /* ep_list */ | ||
1957 | u3d->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ | ||
1958 | |||
1959 | /* the "gadget" abstracts/virtualizes the controller */ | ||
1960 | dev_set_name(&u3d->gadget.dev, "gadget"); | ||
1961 | u3d->gadget.dev.parent = &dev->dev; | ||
1962 | u3d->gadget.dev.dma_mask = dev->dev.dma_mask; | ||
1963 | u3d->gadget.dev.release = mv_u3d_gadget_release; | ||
1964 | u3d->gadget.name = driver_name; /* gadget name */ | ||
1965 | |||
1966 | retval = device_register(&u3d->gadget.dev); | ||
1967 | if (retval) | ||
1968 | goto err_register_gadget_device; | ||
1969 | |||
1970 | mv_u3d_eps_init(u3d); | ||
1971 | |||
1972 | /* external vbus detection */ | ||
1973 | if (u3d->vbus) { | ||
1974 | u3d->clock_gating = 1; | ||
1975 | dev_err(&dev->dev, "external vbus detection\n"); | ||
1976 | } | ||
1977 | |||
1978 | if (!u3d->clock_gating) | ||
1979 | u3d->vbus_active = 1; | ||
1980 | |||
1981 | /* enable usb3 controller vbus detection */ | ||
1982 | u3d->vbus_valid_detect = 1; | ||
1983 | |||
1984 | retval = usb_add_gadget_udc(&dev->dev, &u3d->gadget); | ||
1985 | if (retval) | ||
1986 | goto err_unregister; | ||
1987 | |||
1988 | dev_dbg(&dev->dev, "successful probe usb3 device %s clock gating.\n", | ||
1989 | u3d->clock_gating ? "with" : "without"); | ||
1990 | |||
1991 | return 0; | ||
1992 | |||
1993 | err_unregister: | ||
1994 | device_unregister(&u3d->gadget.dev); | ||
1995 | err_register_gadget_device: | ||
1996 | free_irq(u3d->irq, &dev->dev); | ||
1997 | err_request_irq: | ||
1998 | err_get_irq: | ||
1999 | kfree(u3d->status_req); | ||
2000 | err_alloc_status_req: | ||
2001 | kfree(u3d->eps); | ||
2002 | err_alloc_eps: | ||
2003 | dma_pool_destroy(u3d->trb_pool); | ||
2004 | err_alloc_trb_pool: | ||
2005 | dma_free_coherent(&dev->dev, u3d->ep_context_size, | ||
2006 | u3d->ep_context, u3d->ep_context_dma); | ||
2007 | err_alloc_ep_context: | ||
2008 | if (pdata->phy_deinit) | ||
2009 | pdata->phy_deinit(u3d->phy_regs); | ||
2010 | clk_disable(u3d->clk); | ||
2011 | err_u3d_enable: | ||
2012 | iounmap(u3d->cap_regs); | ||
2013 | err_map_cap_regs: | ||
2014 | err_get_cap_regs: | ||
2015 | err_get_clk: | ||
2016 | clk_put(u3d->clk); | ||
2017 | platform_set_drvdata(dev, NULL); | ||
2018 | kfree(u3d); | ||
2019 | err_alloc_private: | ||
2020 | err_pdata: | ||
2021 | return retval; | ||
2022 | } | ||
2023 | |||
2024 | #ifdef CONFIG_PM | ||
2025 | static int mv_u3d_suspend(struct device *dev) | ||
2026 | { | ||
2027 | struct mv_u3d *u3d = dev_get_drvdata(dev); | ||
2028 | |||
2029 | /* | ||
2030 | * only cable is unplugged, usb can suspend. | ||
2031 | * So do not care about clock_gating == 1, it is handled by | ||
2032 | * vbus session. | ||
2033 | */ | ||
2034 | if (!u3d->clock_gating) { | ||
2035 | mv_u3d_controller_stop(u3d); | ||
2036 | |||
2037 | spin_lock_irq(&u3d->lock); | ||
2038 | /* stop all usb activities */ | ||
2039 | mv_u3d_stop_activity(u3d, u3d->driver); | ||
2040 | spin_unlock_irq(&u3d->lock); | ||
2041 | |||
2042 | mv_u3d_disable(u3d); | ||
2043 | } | ||
2044 | |||
2045 | return 0; | ||
2046 | } | ||
2047 | |||
2048 | static int mv_u3d_resume(struct device *dev) | ||
2049 | { | ||
2050 | struct mv_u3d *u3d = dev_get_drvdata(dev); | ||
2051 | int retval; | ||
2052 | |||
2053 | if (!u3d->clock_gating) { | ||
2054 | retval = mv_u3d_enable(u3d); | ||
2055 | if (retval) | ||
2056 | return retval; | ||
2057 | |||
2058 | if (u3d->driver && u3d->softconnect) { | ||
2059 | mv_u3d_controller_reset(u3d); | ||
2060 | mv_u3d_ep0_reset(u3d); | ||
2061 | mv_u3d_controller_start(u3d); | ||
2062 | } | ||
2063 | } | ||
2064 | |||
2065 | return 0; | ||
2066 | } | ||
2067 | |||
2068 | SIMPLE_DEV_PM_OPS(mv_u3d_pm_ops, mv_u3d_suspend, mv_u3d_resume); | ||
2069 | #endif | ||
2070 | |||
2071 | static void mv_u3d_shutdown(struct platform_device *dev) | ||
2072 | { | ||
2073 | struct mv_u3d *u3d = dev_get_drvdata(&dev->dev); | ||
2074 | u32 tmp; | ||
2075 | |||
2076 | tmp = ioread32(&u3d->op_regs->usbcmd); | ||
2077 | tmp &= ~MV_U3D_CMD_RUN_STOP; | ||
2078 | iowrite32(tmp, &u3d->op_regs->usbcmd); | ||
2079 | } | ||
2080 | |||
2081 | static struct platform_driver mv_u3d_driver = { | ||
2082 | .probe = mv_u3d_probe, | ||
2083 | .remove = __exit_p(mv_u3d_remove), | ||
2084 | .shutdown = mv_u3d_shutdown, | ||
2085 | .driver = { | ||
2086 | .owner = THIS_MODULE, | ||
2087 | .name = "mv-u3d", | ||
2088 | #ifdef CONFIG_PM | ||
2089 | .pm = &mv_u3d_pm_ops, | ||
2090 | #endif | ||
2091 | }, | ||
2092 | }; | ||
2093 | |||
2094 | module_platform_driver(mv_u3d_driver); | ||
2095 | MODULE_ALIAS("platform:mv-u3d"); | ||
2096 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
2097 | MODULE_AUTHOR("Yu Xu <yuxu@marvell.com>"); | ||
2098 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index a460e8c204f4..b26c7d68cc06 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -36,9 +36,9 @@ | |||
36 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
37 | #include <linux/clk.h> | 37 | #include <linux/clk.h> |
38 | #include <linux/prefetch.h> | 38 | #include <linux/prefetch.h> |
39 | #include <linux/io.h> | ||
39 | 40 | ||
40 | #include <asm/byteorder.h> | 41 | #include <asm/byteorder.h> |
41 | #include <asm/io.h> | ||
42 | #include <asm/irq.h> | 42 | #include <asm/irq.h> |
43 | #include <asm/unaligned.h> | 43 | #include <asm/unaligned.h> |
44 | #include <asm/mach-types.h> | 44 | #include <asm/mach-types.h> |
@@ -59,11 +59,6 @@ | |||
59 | #define DRIVER_DESC "OMAP UDC driver" | 59 | #define DRIVER_DESC "OMAP UDC driver" |
60 | #define DRIVER_VERSION "4 October 2004" | 60 | #define DRIVER_VERSION "4 October 2004" |
61 | 61 | ||
62 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
63 | |||
64 | #define OMAP2_DMA_CH(ch) (((ch) - 1) << 1) | ||
65 | #define OMAP24XX_DMA(name, ch) (OMAP24XX_DMA_##name + OMAP2_DMA_CH(ch)) | ||
66 | |||
67 | /* | 62 | /* |
68 | * The OMAP UDC needs _very_ early endpoint setup: before enabling the | 63 | * The OMAP UDC needs _very_ early endpoint setup: before enabling the |
69 | * D+ pullup to allow enumeration. That's too early for the gadget | 64 | * D+ pullup to allow enumeration. That's too early for the gadget |
@@ -87,14 +82,14 @@ | |||
87 | #ifdef USE_ISO | 82 | #ifdef USE_ISO |
88 | static unsigned fifo_mode = 3; | 83 | static unsigned fifo_mode = 3; |
89 | #else | 84 | #else |
90 | static unsigned fifo_mode = 0; | 85 | static unsigned fifo_mode; |
91 | #endif | 86 | #endif |
92 | 87 | ||
93 | /* "modprobe omap_udc fifo_mode=42", or else as a kernel | 88 | /* "modprobe omap_udc fifo_mode=42", or else as a kernel |
94 | * boot parameter "omap_udc:fifo_mode=42" | 89 | * boot parameter "omap_udc:fifo_mode=42" |
95 | */ | 90 | */ |
96 | module_param (fifo_mode, uint, 0); | 91 | module_param(fifo_mode, uint, 0); |
97 | MODULE_PARM_DESC (fifo_mode, "endpoint configuration"); | 92 | MODULE_PARM_DESC(fifo_mode, "endpoint configuration"); |
98 | 93 | ||
99 | #ifdef USE_DMA | 94 | #ifdef USE_DMA |
100 | static bool use_dma = 1; | 95 | static bool use_dma = 1; |
@@ -102,8 +97,8 @@ static bool use_dma = 1; | |||
102 | /* "modprobe omap_udc use_dma=y", or else as a kernel | 97 | /* "modprobe omap_udc use_dma=y", or else as a kernel |
103 | * boot parameter "omap_udc:use_dma=y" | 98 | * boot parameter "omap_udc:use_dma=y" |
104 | */ | 99 | */ |
105 | module_param (use_dma, bool, 0); | 100 | module_param(use_dma, bool, 0); |
106 | MODULE_PARM_DESC (use_dma, "enable/disable DMA"); | 101 | MODULE_PARM_DESC(use_dma, "enable/disable DMA"); |
107 | #else /* !USE_DMA */ | 102 | #else /* !USE_DMA */ |
108 | 103 | ||
109 | /* save a bit of code */ | 104 | /* save a bit of code */ |
@@ -111,8 +106,8 @@ MODULE_PARM_DESC (use_dma, "enable/disable DMA"); | |||
111 | #endif /* !USE_DMA */ | 106 | #endif /* !USE_DMA */ |
112 | 107 | ||
113 | 108 | ||
114 | static const char driver_name [] = "omap_udc"; | 109 | static const char driver_name[] = "omap_udc"; |
115 | static const char driver_desc [] = DRIVER_DESC; | 110 | static const char driver_desc[] = DRIVER_DESC; |
116 | 111 | ||
117 | /*-------------------------------------------------------------------------*/ | 112 | /*-------------------------------------------------------------------------*/ |
118 | 113 | ||
@@ -250,7 +245,7 @@ static int omap_ep_disable(struct usb_ep *_ep) | |||
250 | 245 | ||
251 | spin_lock_irqsave(&ep->udc->lock, flags); | 246 | spin_lock_irqsave(&ep->udc->lock, flags); |
252 | ep->ep.desc = NULL; | 247 | ep->ep.desc = NULL; |
253 | nuke (ep, -ESHUTDOWN); | 248 | nuke(ep, -ESHUTDOWN); |
254 | ep->ep.maxpacket = ep->maxpacket; | 249 | ep->ep.maxpacket = ep->maxpacket; |
255 | ep->has_dma = 0; | 250 | ep->has_dma = 0; |
256 | omap_writew(UDC_SET_HALT, UDC_CTRL); | 251 | omap_writew(UDC_SET_HALT, UDC_CTRL); |
@@ -271,10 +266,11 @@ omap_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) | |||
271 | struct omap_req *req; | 266 | struct omap_req *req; |
272 | 267 | ||
273 | req = kzalloc(sizeof(*req), gfp_flags); | 268 | req = kzalloc(sizeof(*req), gfp_flags); |
274 | if (req) { | 269 | if (!req) |
275 | req->req.dma = DMA_ADDR_INVALID; | 270 | return NULL; |
276 | INIT_LIST_HEAD (&req->queue); | 271 | |
277 | } | 272 | INIT_LIST_HEAD(&req->queue); |
273 | |||
278 | return &req->req; | 274 | return &req->req; |
279 | } | 275 | } |
280 | 276 | ||
@@ -283,8 +279,7 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req) | |||
283 | { | 279 | { |
284 | struct omap_req *req = container_of(_req, struct omap_req, req); | 280 | struct omap_req *req = container_of(_req, struct omap_req, req); |
285 | 281 | ||
286 | if (_req) | 282 | kfree(req); |
287 | kfree (req); | ||
288 | } | 283 | } |
289 | 284 | ||
290 | /*-------------------------------------------------------------------------*/ | 285 | /*-------------------------------------------------------------------------*/ |
@@ -292,6 +287,7 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req) | |||
292 | static void | 287 | static void |
293 | done(struct omap_ep *ep, struct omap_req *req, int status) | 288 | done(struct omap_ep *ep, struct omap_req *req, int status) |
294 | { | 289 | { |
290 | struct omap_udc *udc = ep->udc; | ||
295 | unsigned stopped = ep->stopped; | 291 | unsigned stopped = ep->stopped; |
296 | 292 | ||
297 | list_del_init(&req->queue); | 293 | list_del_init(&req->queue); |
@@ -301,22 +297,9 @@ done(struct omap_ep *ep, struct omap_req *req, int status) | |||
301 | else | 297 | else |
302 | status = req->req.status; | 298 | status = req->req.status; |
303 | 299 | ||
304 | if (use_dma && ep->has_dma) { | 300 | if (use_dma && ep->has_dma) |
305 | if (req->mapped) { | 301 | usb_gadget_unmap_request(&udc->gadget, &req->req, |
306 | dma_unmap_single(ep->udc->gadget.dev.parent, | 302 | (ep->bEndpointAddress & USB_DIR_IN)); |
307 | req->req.dma, req->req.length, | ||
308 | (ep->bEndpointAddress & USB_DIR_IN) | ||
309 | ? DMA_TO_DEVICE | ||
310 | : DMA_FROM_DEVICE); | ||
311 | req->req.dma = DMA_ADDR_INVALID; | ||
312 | req->mapped = 0; | ||
313 | } else | ||
314 | dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, | ||
315 | req->req.dma, req->req.length, | ||
316 | (ep->bEndpointAddress & USB_DIR_IN) | ||
317 | ? DMA_TO_DEVICE | ||
318 | : DMA_FROM_DEVICE); | ||
319 | } | ||
320 | 303 | ||
321 | #ifndef USB_TRACE | 304 | #ifndef USB_TRACE |
322 | if (status && status != -ESHUTDOWN) | 305 | if (status && status != -ESHUTDOWN) |
@@ -364,10 +347,10 @@ write_packet(u8 *buf, struct omap_req *req, unsigned max) | |||
364 | return len; | 347 | return len; |
365 | } | 348 | } |
366 | 349 | ||
367 | // FIXME change r/w fifo calling convention | 350 | /* FIXME change r/w fifo calling convention */ |
368 | 351 | ||
369 | 352 | ||
370 | // return: 0 = still running, 1 = completed, negative = errno | 353 | /* return: 0 = still running, 1 = completed, negative = errno */ |
371 | static int write_fifo(struct omap_ep *ep, struct omap_req *req) | 354 | static int write_fifo(struct omap_ep *ep, struct omap_req *req) |
372 | { | 355 | { |
373 | u8 *buf; | 356 | u8 *buf; |
@@ -429,7 +412,7 @@ read_packet(u8 *buf, struct omap_req *req, unsigned avail) | |||
429 | return len; | 412 | return len; |
430 | } | 413 | } |
431 | 414 | ||
432 | // return: 0 = still running, 1 = queue empty, negative = errno | 415 | /* return: 0 = still running, 1 = queue empty, negative = errno */ |
433 | static int read_fifo(struct omap_ep *ep, struct omap_req *req) | 416 | static int read_fifo(struct omap_ep *ep, struct omap_req *req) |
434 | { | 417 | { |
435 | u8 *buf; | 418 | u8 *buf; |
@@ -536,12 +519,8 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) | |||
536 | : OMAP_DMA_SYNC_ELEMENT; | 519 | : OMAP_DMA_SYNC_ELEMENT; |
537 | int dma_trigger = 0; | 520 | int dma_trigger = 0; |
538 | 521 | ||
539 | if (cpu_is_omap24xx()) | ||
540 | dma_trigger = OMAP24XX_DMA(USB_W2FC_TX0, ep->dma_channel); | ||
541 | |||
542 | /* measure length in either bytes or packets */ | 522 | /* measure length in either bytes or packets */ |
543 | if ((cpu_is_omap16xx() && length <= UDC_TXN_TSC) | 523 | if ((cpu_is_omap16xx() && length <= UDC_TXN_TSC) |
544 | || (cpu_is_omap24xx() && length < ep->maxpacket) | ||
545 | || (cpu_is_omap15xx() && length < ep->maxpacket)) { | 524 | || (cpu_is_omap15xx() && length < ep->maxpacket)) { |
546 | txdma_ctrl = UDC_TXN_EOT | length; | 525 | txdma_ctrl = UDC_TXN_EOT | length; |
547 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, | 526 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, |
@@ -600,28 +579,14 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) | |||
600 | int dma_trigger = 0; | 579 | int dma_trigger = 0; |
601 | u16 w; | 580 | u16 w; |
602 | 581 | ||
603 | if (cpu_is_omap24xx()) | 582 | /* set up this DMA transfer, enable the fifo, start */ |
604 | dma_trigger = OMAP24XX_DMA(USB_W2FC_RX0, ep->dma_channel); | 583 | packets /= ep->ep.maxpacket; |
605 | 584 | packets = min(packets, (unsigned)UDC_RXN_TC + 1); | |
606 | /* NOTE: we filtered out "short reads" before, so we know | 585 | req->dma_bytes = packets * ep->ep.maxpacket; |
607 | * the buffer has only whole numbers of packets. | 586 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, |
608 | * except MODE SELECT(6) sent the 24 bytes data in OMAP24XX DMA mode | 587 | ep->ep.maxpacket >> 1, packets, |
609 | */ | 588 | OMAP_DMA_SYNC_ELEMENT, |
610 | if (cpu_is_omap24xx() && packets < ep->maxpacket) { | 589 | dma_trigger, 0); |
611 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, | ||
612 | packets, 1, OMAP_DMA_SYNC_ELEMENT, | ||
613 | dma_trigger, 0); | ||
614 | req->dma_bytes = packets; | ||
615 | } else { | ||
616 | /* set up this DMA transfer, enable the fifo, start */ | ||
617 | packets /= ep->ep.maxpacket; | ||
618 | packets = min(packets, (unsigned)UDC_RXN_TC + 1); | ||
619 | req->dma_bytes = packets * ep->ep.maxpacket; | ||
620 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, | ||
621 | ep->ep.maxpacket >> 1, packets, | ||
622 | OMAP_DMA_SYNC_ELEMENT, | ||
623 | dma_trigger, 0); | ||
624 | } | ||
625 | omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, | 590 | omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, |
626 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual, | 591 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual, |
627 | 0, 0); | 592 | 0, 0); |
@@ -683,7 +648,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) | |||
683 | } | 648 | } |
684 | omap_writew(UDC_TXN_DONE, UDC_IRQ_SRC); | 649 | omap_writew(UDC_TXN_DONE, UDC_IRQ_SRC); |
685 | 650 | ||
686 | if (!list_empty (&ep->queue)) { | 651 | if (!list_empty(&ep->queue)) { |
687 | req = container_of(ep->queue.next, | 652 | req = container_of(ep->queue.next, |
688 | struct omap_req, queue); | 653 | struct omap_req, queue); |
689 | next_in_dma(ep, req); | 654 | next_in_dma(ep, req); |
@@ -702,7 +667,7 @@ static void dma_irq(struct omap_udc *udc, u16 irq_src) | |||
702 | } | 667 | } |
703 | omap_writew(UDC_RXN_EOT, UDC_IRQ_SRC); | 668 | omap_writew(UDC_RXN_EOT, UDC_IRQ_SRC); |
704 | 669 | ||
705 | if (!list_empty (&ep->queue)) { | 670 | if (!list_empty(&ep->queue)) { |
706 | req = container_of(ep->queue.next, | 671 | req = container_of(ep->queue.next, |
707 | struct omap_req, queue); | 672 | struct omap_req, queue); |
708 | next_out_dma(ep, req); | 673 | next_out_dma(ep, req); |
@@ -760,10 +725,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
760 | ep->dma_channel = channel; | 725 | ep->dma_channel = channel; |
761 | 726 | ||
762 | if (is_in) { | 727 | if (is_in) { |
763 | if (cpu_is_omap24xx()) | 728 | dma_channel = OMAP_DMA_USB_W2FC_TX0 - 1 + channel; |
764 | dma_channel = OMAP24XX_DMA(USB_W2FC_TX0, channel); | ||
765 | else | ||
766 | dma_channel = OMAP_DMA_USB_W2FC_TX0 - 1 + channel; | ||
767 | status = omap_request_dma(dma_channel, | 729 | status = omap_request_dma(dma_channel, |
768 | ep->ep.name, dma_error, ep, &ep->lch); | 730 | ep->ep.name, dma_error, ep, &ep->lch); |
769 | if (status == 0) { | 731 | if (status == 0) { |
@@ -780,11 +742,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
780 | 0, 0); | 742 | 0, 0); |
781 | } | 743 | } |
782 | } else { | 744 | } else { |
783 | if (cpu_is_omap24xx()) | 745 | dma_channel = OMAP_DMA_USB_W2FC_RX0 - 1 + channel; |
784 | dma_channel = OMAP24XX_DMA(USB_W2FC_RX0, channel); | ||
785 | else | ||
786 | dma_channel = OMAP_DMA_USB_W2FC_RX0 - 1 + channel; | ||
787 | |||
788 | status = omap_request_dma(dma_channel, | 746 | status = omap_request_dma(dma_channel, |
789 | ep->ep.name, dma_error, ep, &ep->lch); | 747 | ep->ep.name, dma_error, ep, &ep->lch); |
790 | if (status == 0) { | 748 | if (status == 0) { |
@@ -808,7 +766,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
808 | omap_disable_dma_irq(ep->lch, OMAP_DMA_BLOCK_IRQ); | 766 | omap_disable_dma_irq(ep->lch, OMAP_DMA_BLOCK_IRQ); |
809 | 767 | ||
810 | /* channel type P: hw synch (fifo) */ | 768 | /* channel type P: hw synch (fifo) */ |
811 | if (cpu_class_is_omap1() && !cpu_is_omap15xx()) | 769 | if (!cpu_is_omap15xx()) |
812 | omap_set_dma_channel_mode(ep->lch, OMAP_DMA_LCH_P); | 770 | omap_set_dma_channel_mode(ep->lch, OMAP_DMA_LCH_P); |
813 | } | 771 | } |
814 | 772 | ||
@@ -928,13 +886,11 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
928 | 886 | ||
929 | /* this isn't bogus, but OMAP DMA isn't the only hardware to | 887 | /* this isn't bogus, but OMAP DMA isn't the only hardware to |
930 | * have a hard time with partial packet reads... reject it. | 888 | * have a hard time with partial packet reads... reject it. |
931 | * Except OMAP2 can handle the small packets. | ||
932 | */ | 889 | */ |
933 | if (use_dma | 890 | if (use_dma |
934 | && ep->has_dma | 891 | && ep->has_dma |
935 | && ep->bEndpointAddress != 0 | 892 | && ep->bEndpointAddress != 0 |
936 | && (ep->bEndpointAddress & USB_DIR_IN) == 0 | 893 | && (ep->bEndpointAddress & USB_DIR_IN) == 0 |
937 | && !cpu_class_is_omap2() | ||
938 | && (req->req.length % ep->ep.maxpacket) != 0) { | 894 | && (req->req.length % ep->ep.maxpacket) != 0) { |
939 | DBG("%s, no partial packet OUT reads\n", __func__); | 895 | DBG("%s, no partial packet OUT reads\n", __func__); |
940 | return -EMSGSIZE; | 896 | return -EMSGSIZE; |
@@ -944,26 +900,9 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
944 | if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) | 900 | if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) |
945 | return -ESHUTDOWN; | 901 | return -ESHUTDOWN; |
946 | 902 | ||
947 | if (use_dma && ep->has_dma) { | 903 | if (use_dma && ep->has_dma) |
948 | if (req->req.dma == DMA_ADDR_INVALID) { | 904 | usb_gadget_map_request(&udc->gadget, &req->req, |
949 | req->req.dma = dma_map_single( | 905 | (ep->bEndpointAddress & USB_DIR_IN)); |
950 | ep->udc->gadget.dev.parent, | ||
951 | req->req.buf, | ||
952 | req->req.length, | ||
953 | (ep->bEndpointAddress & USB_DIR_IN) | ||
954 | ? DMA_TO_DEVICE | ||
955 | : DMA_FROM_DEVICE); | ||
956 | req->mapped = 1; | ||
957 | } else { | ||
958 | dma_sync_single_for_device( | ||
959 | ep->udc->gadget.dev.parent, | ||
960 | req->req.dma, req->req.length, | ||
961 | (ep->bEndpointAddress & USB_DIR_IN) | ||
962 | ? DMA_TO_DEVICE | ||
963 | : DMA_FROM_DEVICE); | ||
964 | req->mapped = 0; | ||
965 | } | ||
966 | } | ||
967 | 906 | ||
968 | VDBG("%s queue req %p, len %d buf %p\n", | 907 | VDBG("%s queue req %p, len %d buf %p\n", |
969 | ep->ep.name, _req, _req->length, _req->buf); | 908 | ep->ep.name, _req, _req->length, _req->buf); |
@@ -984,7 +923,7 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
984 | int is_in; | 923 | int is_in; |
985 | 924 | ||
986 | if (ep->bEndpointAddress == 0) { | 925 | if (ep->bEndpointAddress == 0) { |
987 | if (!udc->ep0_pending || !list_empty (&ep->queue)) { | 926 | if (!udc->ep0_pending || !list_empty(&ep->queue)) { |
988 | spin_unlock_irqrestore(&udc->lock, flags); | 927 | spin_unlock_irqrestore(&udc->lock, flags); |
989 | return -EL2HLT; | 928 | return -EL2HLT; |
990 | } | 929 | } |
@@ -1011,7 +950,8 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
1011 | * always an IN ... even for IN transfers, | 950 | * always an IN ... even for IN transfers, |
1012 | * a weird case which seem to stall OMAP. | 951 | * a weird case which seem to stall OMAP. |
1013 | */ | 952 | */ |
1014 | omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM); | 953 | omap_writew(UDC_EP_SEL | UDC_EP_DIR, |
954 | UDC_EP_NUM); | ||
1015 | omap_writew(UDC_CLR_EP, UDC_CTRL); | 955 | omap_writew(UDC_CLR_EP, UDC_CTRL); |
1016 | omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); | 956 | omap_writew(UDC_SET_FIFO_EN, UDC_CTRL); |
1017 | omap_writew(UDC_EP_DIR, UDC_EP_NUM); | 957 | omap_writew(UDC_EP_DIR, UDC_EP_NUM); |
@@ -1023,7 +963,8 @@ omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
1023 | 963 | ||
1024 | /* non-empty DATA stage */ | 964 | /* non-empty DATA stage */ |
1025 | } else if (is_in) { | 965 | } else if (is_in) { |
1026 | omap_writew(UDC_EP_SEL | UDC_EP_DIR, UDC_EP_NUM); | 966 | omap_writew(UDC_EP_SEL | UDC_EP_DIR, |
967 | UDC_EP_NUM); | ||
1027 | } else { | 968 | } else { |
1028 | if (udc->ep0_setup) | 969 | if (udc->ep0_setup) |
1029 | goto irq_wait; | 970 | goto irq_wait; |
@@ -1071,7 +1012,7 @@ static int omap_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
1071 | spin_lock_irqsave(&ep->udc->lock, flags); | 1012 | spin_lock_irqsave(&ep->udc->lock, flags); |
1072 | 1013 | ||
1073 | /* make sure it's actually queued on this endpoint */ | 1014 | /* make sure it's actually queued on this endpoint */ |
1074 | list_for_each_entry (req, &ep->queue, queue) { | 1015 | list_for_each_entry(req, &ep->queue, queue) { |
1075 | if (&req->req == _req) | 1016 | if (&req->req == _req) |
1076 | break; | 1017 | break; |
1077 | } | 1018 | } |
@@ -1178,8 +1119,8 @@ static struct usb_ep_ops omap_ep_ops = { | |||
1178 | .dequeue = omap_ep_dequeue, | 1119 | .dequeue = omap_ep_dequeue, |
1179 | 1120 | ||
1180 | .set_halt = omap_ep_set_halt, | 1121 | .set_halt = omap_ep_set_halt, |
1181 | // fifo_status ... report bytes in fifo | 1122 | /* fifo_status ... report bytes in fifo */ |
1182 | // fifo_flush ... flush fifo | 1123 | /* fifo_flush ... flush fifo */ |
1183 | }; | 1124 | }; |
1184 | 1125 | ||
1185 | /*-------------------------------------------------------------------------*/ | 1126 | /*-------------------------------------------------------------------------*/ |
@@ -1409,7 +1350,7 @@ static void udc_quiesce(struct omap_udc *udc) | |||
1409 | 1350 | ||
1410 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1351 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1411 | nuke(&udc->ep[0], -ESHUTDOWN); | 1352 | nuke(&udc->ep[0], -ESHUTDOWN); |
1412 | list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) | 1353 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) |
1413 | nuke(ep, -ESHUTDOWN); | 1354 | nuke(ep, -ESHUTDOWN); |
1414 | } | 1355 | } |
1415 | 1356 | ||
@@ -1525,7 +1466,8 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1525 | /* read next OUT packet of request, maybe | 1466 | /* read next OUT packet of request, maybe |
1526 | * reactiviting the fifo; stall on errors. | 1467 | * reactiviting the fifo; stall on errors. |
1527 | */ | 1468 | */ |
1528 | if (!req || (stat = read_fifo(ep0, req)) < 0) { | 1469 | stat = read_fifo(ep0, req); |
1470 | if (!req || stat < 0) { | ||
1529 | omap_writew(UDC_STALL_CMD, UDC_SYSCON2); | 1471 | omap_writew(UDC_STALL_CMD, UDC_SYSCON2); |
1530 | udc->ep0_pending = 0; | 1472 | udc->ep0_pending = 0; |
1531 | stat = 0; | 1473 | stat = 0; |
@@ -1658,7 +1600,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1658 | /* this has rude side-effects (aborts) and | 1600 | /* this has rude side-effects (aborts) and |
1659 | * can't really work if DMA-IN is active | 1601 | * can't really work if DMA-IN is active |
1660 | */ | 1602 | */ |
1661 | DBG("%s host set_halt, NYET \n", ep->name); | 1603 | DBG("%s host set_halt, NYET\n", ep->name); |
1662 | goto do_stall; | 1604 | goto do_stall; |
1663 | } | 1605 | } |
1664 | use_ep(ep, 0); | 1606 | use_ep(ep, 0); |
@@ -1749,7 +1691,7 @@ delegate: | |||
1749 | */ | 1691 | */ |
1750 | udc->ep0_setup = 1; | 1692 | udc->ep0_setup = 1; |
1751 | spin_unlock(&udc->lock); | 1693 | spin_unlock(&udc->lock); |
1752 | status = udc->driver->setup (&udc->gadget, &u.r); | 1694 | status = udc->driver->setup(&udc->gadget, &u.r); |
1753 | spin_lock(&udc->lock); | 1695 | spin_lock(&udc->lock); |
1754 | udc->ep0_setup = 0; | 1696 | udc->ep0_setup = 0; |
1755 | } | 1697 | } |
@@ -1794,7 +1736,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) | |||
1794 | VDBG("connect\n"); | 1736 | VDBG("connect\n"); |
1795 | if (!udc->transceiver) | 1737 | if (!udc->transceiver) |
1796 | pullup_enable(udc); | 1738 | pullup_enable(udc); |
1797 | // if (driver->connect) call it | 1739 | /* if (driver->connect) call it */ |
1798 | } else if (udc->gadget.speed != USB_SPEED_UNKNOWN) { | 1740 | } else if (udc->gadget.speed != USB_SPEED_UNKNOWN) { |
1799 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1741 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1800 | if (!udc->transceiver) | 1742 | if (!udc->transceiver) |
@@ -1826,7 +1768,7 @@ static void devstate_irq(struct omap_udc *udc, u16 irq_src) | |||
1826 | } | 1768 | } |
1827 | if (change & UDC_SUS) { | 1769 | if (change & UDC_SUS) { |
1828 | if (udc->gadget.speed != USB_SPEED_UNKNOWN) { | 1770 | if (udc->gadget.speed != USB_SPEED_UNKNOWN) { |
1829 | // FIXME tell isp1301 to suspend/resume (?) | 1771 | /* FIXME tell isp1301 to suspend/resume (?) */ |
1830 | if (devstat & UDC_SUS) { | 1772 | if (devstat & UDC_SUS) { |
1831 | VDBG("suspend\n"); | 1773 | VDBG("suspend\n"); |
1832 | update_otg(udc); | 1774 | update_otg(udc); |
@@ -2029,7 +1971,7 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) | |||
2029 | spin_lock_irqsave(&udc->lock, flags); | 1971 | spin_lock_irqsave(&udc->lock, flags); |
2030 | 1972 | ||
2031 | /* handle all non-DMA ISO transfers */ | 1973 | /* handle all non-DMA ISO transfers */ |
2032 | list_for_each_entry (ep, &udc->iso, iso) { | 1974 | list_for_each_entry(ep, &udc->iso, iso) { |
2033 | u16 stat; | 1975 | u16 stat; |
2034 | struct omap_req *req; | 1976 | struct omap_req *req; |
2035 | 1977 | ||
@@ -2088,15 +2030,11 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) | |||
2088 | 2030 | ||
2089 | static inline int machine_without_vbus_sense(void) | 2031 | static inline int machine_without_vbus_sense(void) |
2090 | { | 2032 | { |
2091 | return (machine_is_omap_innovator() | 2033 | return machine_is_omap_innovator() |
2092 | || machine_is_omap_osk() | 2034 | || machine_is_omap_osk() |
2093 | || machine_is_omap_apollon() | ||
2094 | #ifndef CONFIG_MACH_OMAP_H4_OTG | ||
2095 | || machine_is_omap_h4() | ||
2096 | #endif | ||
2097 | || machine_is_sx1() | 2035 | || machine_is_sx1() |
2098 | || cpu_is_omap7xx() /* No known omap7xx boards with vbus sense */ | 2036 | /* No known omap7xx boards with vbus sense */ |
2099 | ); | 2037 | || cpu_is_omap7xx(); |
2100 | } | 2038 | } |
2101 | 2039 | ||
2102 | static int omap_udc_start(struct usb_gadget_driver *driver, | 2040 | static int omap_udc_start(struct usb_gadget_driver *driver, |
@@ -2110,7 +2048,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver, | |||
2110 | if (!udc) | 2048 | if (!udc) |
2111 | return -ENODEV; | 2049 | return -ENODEV; |
2112 | if (!driver | 2050 | if (!driver |
2113 | // FIXME if otg, check: driver->is_otg | 2051 | /* FIXME if otg, check: driver->is_otg */ |
2114 | || driver->max_speed < USB_SPEED_FULL | 2052 | || driver->max_speed < USB_SPEED_FULL |
2115 | || !bind || !driver->setup) | 2053 | || !bind || !driver->setup) |
2116 | return -EINVAL; | 2054 | return -EINVAL; |
@@ -2122,7 +2060,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver, | |||
2122 | } | 2060 | } |
2123 | 2061 | ||
2124 | /* reset state */ | 2062 | /* reset state */ |
2125 | list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) { | 2063 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { |
2126 | ep->irqs = 0; | 2064 | ep->irqs = 0; |
2127 | if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) | 2065 | if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) |
2128 | continue; | 2066 | continue; |
@@ -2160,7 +2098,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver, | |||
2160 | if (status < 0) { | 2098 | if (status < 0) { |
2161 | ERR("can't bind to transceiver\n"); | 2099 | ERR("can't bind to transceiver\n"); |
2162 | if (driver->unbind) { | 2100 | if (driver->unbind) { |
2163 | driver->unbind (&udc->gadget); | 2101 | driver->unbind(&udc->gadget); |
2164 | udc->gadget.dev.driver = NULL; | 2102 | udc->gadget.dev.driver = NULL; |
2165 | udc->driver = NULL; | 2103 | udc->driver = NULL; |
2166 | } | 2104 | } |
@@ -2168,9 +2106,9 @@ static int omap_udc_start(struct usb_gadget_driver *driver, | |||
2168 | } | 2106 | } |
2169 | } else { | 2107 | } else { |
2170 | if (can_pullup(udc)) | 2108 | if (can_pullup(udc)) |
2171 | pullup_enable (udc); | 2109 | pullup_enable(udc); |
2172 | else | 2110 | else |
2173 | pullup_disable (udc); | 2111 | pullup_disable(udc); |
2174 | } | 2112 | } |
2175 | 2113 | ||
2176 | /* boards that don't have VBUS sensing can't autogate 48MHz; | 2114 | /* boards that don't have VBUS sensing can't autogate 48MHz; |
@@ -2229,7 +2167,7 @@ static int omap_udc_stop(struct usb_gadget_driver *driver) | |||
2229 | static const char proc_filename[] = "driver/udc"; | 2167 | static const char proc_filename[] = "driver/udc"; |
2230 | 2168 | ||
2231 | #define FOURBITS "%s%s%s%s" | 2169 | #define FOURBITS "%s%s%s%s" |
2232 | #define EIGHTBITS FOURBITS FOURBITS | 2170 | #define EIGHTBITS "%s%s%s%s%s%s%s%s" |
2233 | 2171 | ||
2234 | static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) | 2172 | static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) |
2235 | { | 2173 | { |
@@ -2251,12 +2189,21 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) | |||
2251 | "\n%s %s%s%sirqs %ld stat %04x " EIGHTBITS FOURBITS "%s\n", | 2189 | "\n%s %s%s%sirqs %ld stat %04x " EIGHTBITS FOURBITS "%s\n", |
2252 | ep->name, buf, | 2190 | ep->name, buf, |
2253 | ep->double_buf ? "dbuf " : "", | 2191 | ep->double_buf ? "dbuf " : "", |
2254 | ({char *s; switch(ep->ackwait){ | 2192 | ({ char *s; |
2255 | case 0: s = ""; break; | 2193 | switch (ep->ackwait) { |
2256 | case 1: s = "(ackw) "; break; | 2194 | case 0: |
2257 | case 2: s = "(ackw2) "; break; | 2195 | s = ""; |
2258 | default: s = "(?) "; break; | 2196 | break; |
2259 | } s;}), | 2197 | case 1: |
2198 | s = "(ackw) "; | ||
2199 | break; | ||
2200 | case 2: | ||
2201 | s = "(ackw2) "; | ||
2202 | break; | ||
2203 | default: | ||
2204 | s = "(?) "; | ||
2205 | break; | ||
2206 | } s; }), | ||
2260 | ep->irqs, stat_flg, | 2207 | ep->irqs, stat_flg, |
2261 | (stat_flg & UDC_NO_RXPACKET) ? "no_rxpacket " : "", | 2208 | (stat_flg & UDC_NO_RXPACKET) ? "no_rxpacket " : "", |
2262 | (stat_flg & UDC_MISS_IN) ? "miss_in " : "", | 2209 | (stat_flg & UDC_MISS_IN) ? "miss_in " : "", |
@@ -2272,10 +2219,10 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) | |||
2272 | (stat_flg & UDC_NON_ISO_FIFO_EMPTY) ? "fifo_empty " : "", | 2219 | (stat_flg & UDC_NON_ISO_FIFO_EMPTY) ? "fifo_empty " : "", |
2273 | (stat_flg & UDC_NON_ISO_FIFO_FULL) ? "fifo_full " : ""); | 2220 | (stat_flg & UDC_NON_ISO_FIFO_FULL) ? "fifo_full " : ""); |
2274 | 2221 | ||
2275 | if (list_empty (&ep->queue)) | 2222 | if (list_empty(&ep->queue)) |
2276 | seq_printf(s, "\t(queue empty)\n"); | 2223 | seq_printf(s, "\t(queue empty)\n"); |
2277 | else | 2224 | else |
2278 | list_for_each_entry (req, &ep->queue, queue) { | 2225 | list_for_each_entry(req, &ep->queue, queue) { |
2279 | unsigned length = req->req.actual; | 2226 | unsigned length = req->req.actual; |
2280 | 2227 | ||
2281 | if (use_dma && buf[0]) { | 2228 | if (use_dma && buf[0]) { |
@@ -2293,11 +2240,16 @@ static void proc_ep_show(struct seq_file *s, struct omap_ep *ep) | |||
2293 | static char *trx_mode(unsigned m, int enabled) | 2240 | static char *trx_mode(unsigned m, int enabled) |
2294 | { | 2241 | { |
2295 | switch (m) { | 2242 | switch (m) { |
2296 | case 0: return enabled ? "*6wire" : "unused"; | 2243 | case 0: |
2297 | case 1: return "4wire"; | 2244 | return enabled ? "*6wire" : "unused"; |
2298 | case 2: return "3wire"; | 2245 | case 1: |
2299 | case 3: return "6wire"; | 2246 | return "4wire"; |
2300 | default: return "unknown"; | 2247 | case 2: |
2248 | return "3wire"; | ||
2249 | case 3: | ||
2250 | return "6wire"; | ||
2251 | default: | ||
2252 | return "unknown"; | ||
2301 | } | 2253 | } |
2302 | } | 2254 | } |
2303 | 2255 | ||
@@ -2307,12 +2259,9 @@ static int proc_otg_show(struct seq_file *s) | |||
2307 | u32 trans = 0; | 2259 | u32 trans = 0; |
2308 | char *ctrl_name = "(UNKNOWN)"; | 2260 | char *ctrl_name = "(UNKNOWN)"; |
2309 | 2261 | ||
2310 | /* XXX This needs major revision for OMAP2+ */ | ||
2311 | tmp = omap_readl(OTG_REV); | 2262 | tmp = omap_readl(OTG_REV); |
2312 | if (cpu_class_is_omap1()) { | 2263 | ctrl_name = "tranceiver_ctrl"; |
2313 | ctrl_name = "tranceiver_ctrl"; | 2264 | trans = omap_readw(USB_TRANSCEIVER_CTRL); |
2314 | trans = omap_readw(USB_TRANSCEIVER_CTRL); | ||
2315 | } | ||
2316 | seq_printf(s, "\nOTG rev %d.%d, %s %05x\n", | 2265 | seq_printf(s, "\nOTG rev %d.%d, %s %05x\n", |
2317 | tmp >> 4, tmp & 0xf, ctrl_name, trans); | 2266 | tmp >> 4, tmp & 0xf, ctrl_name, trans); |
2318 | tmp = omap_readw(OTG_SYSCON_1); | 2267 | tmp = omap_readw(OTG_SYSCON_1); |
@@ -2332,7 +2281,7 @@ static int proc_otg_show(struct seq_file *s) | |||
2332 | " b_ase_brst=%d hmc=%d\n", tmp, | 2281 | " b_ase_brst=%d hmc=%d\n", tmp, |
2333 | (tmp & OTG_EN) ? " otg_en" : "", | 2282 | (tmp & OTG_EN) ? " otg_en" : "", |
2334 | (tmp & USBX_SYNCHRO) ? " synchro" : "", | 2283 | (tmp & USBX_SYNCHRO) ? " synchro" : "", |
2335 | // much more SRP stuff | 2284 | /* much more SRP stuff */ |
2336 | (tmp & SRP_DATA) ? " srp_data" : "", | 2285 | (tmp & SRP_DATA) ? " srp_data" : "", |
2337 | (tmp & SRP_VBUS) ? " srp_vbus" : "", | 2286 | (tmp & SRP_VBUS) ? " srp_vbus" : "", |
2338 | (tmp & OTG_PADEN) ? " otg_paden" : "", | 2287 | (tmp & OTG_PADEN) ? " otg_paden" : "", |
@@ -2399,14 +2348,12 @@ static int proc_udc_show(struct seq_file *s, void *_) | |||
2399 | HMC, | 2348 | HMC, |
2400 | udc->transceiver | 2349 | udc->transceiver |
2401 | ? udc->transceiver->label | 2350 | ? udc->transceiver->label |
2402 | : ((cpu_is_omap1710() || cpu_is_omap24xx()) | 2351 | : (cpu_is_omap1710() |
2403 | ? "external" : "(none)")); | 2352 | ? "external" : "(none)")); |
2404 | if (cpu_class_is_omap1()) { | 2353 | seq_printf(s, "ULPD control %04x req %04x status %04x\n", |
2405 | seq_printf(s, "ULPD control %04x req %04x status %04x\n", | 2354 | omap_readw(ULPD_CLOCK_CTRL), |
2406 | omap_readw(ULPD_CLOCK_CTRL), | 2355 | omap_readw(ULPD_SOFT_REQ), |
2407 | omap_readw(ULPD_SOFT_REQ), | 2356 | omap_readw(ULPD_STATUS_REQ)); |
2408 | omap_readw(ULPD_STATUS_REQ)); | ||
2409 | } | ||
2410 | 2357 | ||
2411 | /* OTG controller registers */ | 2358 | /* OTG controller registers */ |
2412 | if (!cpu_is_omap15xx()) | 2359 | if (!cpu_is_omap15xx()) |
@@ -2422,7 +2369,7 @@ static int proc_udc_show(struct seq_file *s, void *_) | |||
2422 | (tmp & UDC_SELF_PWR) ? " self_pwr" : "", | 2369 | (tmp & UDC_SELF_PWR) ? " self_pwr" : "", |
2423 | (tmp & UDC_SOFF_DIS) ? " soff_dis" : "", | 2370 | (tmp & UDC_SOFF_DIS) ? " soff_dis" : "", |
2424 | (tmp & UDC_PULLUP_EN) ? " PULLUP" : ""); | 2371 | (tmp & UDC_PULLUP_EN) ? " PULLUP" : ""); |
2425 | // syscon2 is write-only | 2372 | /* syscon2 is write-only */ |
2426 | 2373 | ||
2427 | /* UDC controller registers */ | 2374 | /* UDC controller registers */ |
2428 | if (!(tmp & UDC_PULLUP_EN)) { | 2375 | if (!(tmp & UDC_PULLUP_EN)) { |
@@ -2506,7 +2453,7 @@ static int proc_udc_show(struct seq_file *s, void *_) | |||
2506 | if (tmp & UDC_ATT) { | 2453 | if (tmp & UDC_ATT) { |
2507 | proc_ep_show(s, &udc->ep[0]); | 2454 | proc_ep_show(s, &udc->ep[0]); |
2508 | if (tmp & UDC_ADD) { | 2455 | if (tmp & UDC_ADD) { |
2509 | list_for_each_entry (ep, &udc->gadget.ep_list, | 2456 | list_for_each_entry(ep, &udc->gadget.ep_list, |
2510 | ep.ep_list) { | 2457 | ep.ep_list) { |
2511 | if (ep->ep.desc) | 2458 | if (ep->ep.desc) |
2512 | proc_ep_show(s, ep); | 2459 | proc_ep_show(s, ep); |
@@ -2557,7 +2504,7 @@ static inline void remove_proc_file(void) {} | |||
2557 | * UDC_SYSCON_1.CFG_LOCK is set can now work. We won't use that | 2504 | * UDC_SYSCON_1.CFG_LOCK is set can now work. We won't use that |
2558 | * capability yet though. | 2505 | * capability yet though. |
2559 | */ | 2506 | */ |
2560 | static unsigned __init | 2507 | static unsigned __devinit |
2561 | omap_ep_setup(char *name, u8 addr, u8 type, | 2508 | omap_ep_setup(char *name, u8 addr, u8 type, |
2562 | unsigned buf, unsigned maxp, int dbuf) | 2509 | unsigned buf, unsigned maxp, int dbuf) |
2563 | { | 2510 | { |
@@ -2575,14 +2522,29 @@ omap_ep_setup(char *name, u8 addr, u8 type, | |||
2575 | /* chip setup ... bit values are same for IN, OUT */ | 2522 | /* chip setup ... bit values are same for IN, OUT */ |
2576 | if (type == USB_ENDPOINT_XFER_ISOC) { | 2523 | if (type == USB_ENDPOINT_XFER_ISOC) { |
2577 | switch (maxp) { | 2524 | switch (maxp) { |
2578 | case 8: epn_rxtx = 0 << 12; break; | 2525 | case 8: |
2579 | case 16: epn_rxtx = 1 << 12; break; | 2526 | epn_rxtx = 0 << 12; |
2580 | case 32: epn_rxtx = 2 << 12; break; | 2527 | break; |
2581 | case 64: epn_rxtx = 3 << 12; break; | 2528 | case 16: |
2582 | case 128: epn_rxtx = 4 << 12; break; | 2529 | epn_rxtx = 1 << 12; |
2583 | case 256: epn_rxtx = 5 << 12; break; | 2530 | break; |
2584 | case 512: epn_rxtx = 6 << 12; break; | 2531 | case 32: |
2585 | default: BUG(); | 2532 | epn_rxtx = 2 << 12; |
2533 | break; | ||
2534 | case 64: | ||
2535 | epn_rxtx = 3 << 12; | ||
2536 | break; | ||
2537 | case 128: | ||
2538 | epn_rxtx = 4 << 12; | ||
2539 | break; | ||
2540 | case 256: | ||
2541 | epn_rxtx = 5 << 12; | ||
2542 | break; | ||
2543 | case 512: | ||
2544 | epn_rxtx = 6 << 12; | ||
2545 | break; | ||
2546 | default: | ||
2547 | BUG(); | ||
2586 | } | 2548 | } |
2587 | epn_rxtx |= UDC_EPN_RX_ISO; | 2549 | epn_rxtx |= UDC_EPN_RX_ISO; |
2588 | dbuf = 1; | 2550 | dbuf = 1; |
@@ -2591,15 +2553,24 @@ omap_ep_setup(char *name, u8 addr, u8 type, | |||
2591 | * and ignored for PIO-IN on newer chips | 2553 | * and ignored for PIO-IN on newer chips |
2592 | * (for more reliable behavior) | 2554 | * (for more reliable behavior) |
2593 | */ | 2555 | */ |
2594 | if (!use_dma || cpu_is_omap15xx() || cpu_is_omap24xx()) | 2556 | if (!use_dma || cpu_is_omap15xx()) |
2595 | dbuf = 0; | 2557 | dbuf = 0; |
2596 | 2558 | ||
2597 | switch (maxp) { | 2559 | switch (maxp) { |
2598 | case 8: epn_rxtx = 0 << 12; break; | 2560 | case 8: |
2599 | case 16: epn_rxtx = 1 << 12; break; | 2561 | epn_rxtx = 0 << 12; |
2600 | case 32: epn_rxtx = 2 << 12; break; | 2562 | break; |
2601 | case 64: epn_rxtx = 3 << 12; break; | 2563 | case 16: |
2602 | default: BUG(); | 2564 | epn_rxtx = 1 << 12; |
2565 | break; | ||
2566 | case 32: | ||
2567 | epn_rxtx = 2 << 12; | ||
2568 | break; | ||
2569 | case 64: | ||
2570 | epn_rxtx = 3 << 12; | ||
2571 | break; | ||
2572 | default: | ||
2573 | BUG(); | ||
2603 | } | 2574 | } |
2604 | if (dbuf && addr) | 2575 | if (dbuf && addr) |
2605 | epn_rxtx |= UDC_EPN_RX_DB; | 2576 | epn_rxtx |= UDC_EPN_RX_DB; |
@@ -2639,7 +2610,7 @@ omap_ep_setup(char *name, u8 addr, u8 type, | |||
2639 | ep->ep.name = ep->name; | 2610 | ep->ep.name = ep->name; |
2640 | ep->ep.ops = &omap_ep_ops; | 2611 | ep->ep.ops = &omap_ep_ops; |
2641 | ep->ep.maxpacket = ep->maxpacket = maxp; | 2612 | ep->ep.maxpacket = ep->maxpacket = maxp; |
2642 | list_add_tail (&ep->ep.ep_list, &udc->gadget.ep_list); | 2613 | list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); |
2643 | 2614 | ||
2644 | return buf; | 2615 | return buf; |
2645 | } | 2616 | } |
@@ -2647,11 +2618,11 @@ omap_ep_setup(char *name, u8 addr, u8 type, | |||
2647 | static void omap_udc_release(struct device *dev) | 2618 | static void omap_udc_release(struct device *dev) |
2648 | { | 2619 | { |
2649 | complete(udc->done); | 2620 | complete(udc->done); |
2650 | kfree (udc); | 2621 | kfree(udc); |
2651 | udc = NULL; | 2622 | udc = NULL; |
2652 | } | 2623 | } |
2653 | 2624 | ||
2654 | static int __init | 2625 | static int __devinit |
2655 | omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) | 2626 | omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) |
2656 | { | 2627 | { |
2657 | unsigned tmp, buf; | 2628 | unsigned tmp, buf; |
@@ -2665,13 +2636,13 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) | |||
2665 | omap_writew(0, UDC_TXDMA_CFG); | 2636 | omap_writew(0, UDC_TXDMA_CFG); |
2666 | 2637 | ||
2667 | /* UDC_PULLUP_EN gates the chip clock */ | 2638 | /* UDC_PULLUP_EN gates the chip clock */ |
2668 | // OTG_SYSCON_1 |= DEV_IDLE_EN; | 2639 | /* OTG_SYSCON_1 |= DEV_IDLE_EN; */ |
2669 | 2640 | ||
2670 | udc = kzalloc(sizeof(*udc), GFP_KERNEL); | 2641 | udc = kzalloc(sizeof(*udc), GFP_KERNEL); |
2671 | if (!udc) | 2642 | if (!udc) |
2672 | return -ENOMEM; | 2643 | return -ENOMEM; |
2673 | 2644 | ||
2674 | spin_lock_init (&udc->lock); | 2645 | spin_lock_init(&udc->lock); |
2675 | 2646 | ||
2676 | udc->gadget.ops = &omap_gadget_ops; | 2647 | udc->gadget.ops = &omap_gadget_ops; |
2677 | udc->gadget.ep0 = &udc->ep[0].ep; | 2648 | udc->gadget.ep0 = &udc->ep[0].ep; |
@@ -2701,13 +2672,13 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) | |||
2701 | omap_writew(0, UDC_EP_TX(tmp)); | 2672 | omap_writew(0, UDC_EP_TX(tmp)); |
2702 | } | 2673 | } |
2703 | 2674 | ||
2704 | #define OMAP_BULK_EP(name,addr) \ | 2675 | #define OMAP_BULK_EP(name, addr) \ |
2705 | buf = omap_ep_setup(name "-bulk", addr, \ | 2676 | buf = omap_ep_setup(name "-bulk", addr, \ |
2706 | USB_ENDPOINT_XFER_BULK, buf, 64, 1); | 2677 | USB_ENDPOINT_XFER_BULK, buf, 64, 1); |
2707 | #define OMAP_INT_EP(name,addr, maxp) \ | 2678 | #define OMAP_INT_EP(name, addr, maxp) \ |
2708 | buf = omap_ep_setup(name "-int", addr, \ | 2679 | buf = omap_ep_setup(name "-int", addr, \ |
2709 | USB_ENDPOINT_XFER_INT, buf, maxp, 0); | 2680 | USB_ENDPOINT_XFER_INT, buf, maxp, 0); |
2710 | #define OMAP_ISO_EP(name,addr, maxp) \ | 2681 | #define OMAP_ISO_EP(name, addr, maxp) \ |
2711 | buf = omap_ep_setup(name "-iso", addr, \ | 2682 | buf = omap_ep_setup(name "-iso", addr, \ |
2712 | USB_ENDPOINT_XFER_ISOC, buf, maxp, 1); | 2683 | USB_ENDPOINT_XFER_ISOC, buf, maxp, 1); |
2713 | 2684 | ||
@@ -2788,15 +2759,18 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) | |||
2788 | return 0; | 2759 | return 0; |
2789 | } | 2760 | } |
2790 | 2761 | ||
2791 | static int __init omap_udc_probe(struct platform_device *pdev) | 2762 | static int __devinit omap_udc_probe(struct platform_device *pdev) |
2792 | { | 2763 | { |
2793 | int status = -ENODEV; | 2764 | int status = -ENODEV; |
2794 | int hmc; | 2765 | int hmc; |
2795 | struct usb_phy *xceiv = NULL; | 2766 | struct usb_phy *xceiv = NULL; |
2796 | const char *type = NULL; | 2767 | const char *type = NULL; |
2797 | struct omap_usb_config *config = pdev->dev.platform_data; | 2768 | struct omap_usb_config *config = pdev->dev.platform_data; |
2798 | struct clk *dc_clk; | 2769 | struct clk *dc_clk = NULL; |
2799 | struct clk *hhc_clk; | 2770 | struct clk *hhc_clk = NULL; |
2771 | |||
2772 | if (cpu_is_omap7xx()) | ||
2773 | use_dma = 0; | ||
2800 | 2774 | ||
2801 | /* NOTE: "knows" the order of the resources! */ | 2775 | /* NOTE: "knows" the order of the resources! */ |
2802 | if (!request_mem_region(pdev->resource[0].start, | 2776 | if (!request_mem_region(pdev->resource[0].start, |
@@ -2816,16 +2790,6 @@ static int __init omap_udc_probe(struct platform_device *pdev) | |||
2816 | udelay(100); | 2790 | udelay(100); |
2817 | } | 2791 | } |
2818 | 2792 | ||
2819 | if (cpu_is_omap24xx()) { | ||
2820 | dc_clk = clk_get(&pdev->dev, "usb_fck"); | ||
2821 | hhc_clk = clk_get(&pdev->dev, "usb_l4_ick"); | ||
2822 | BUG_ON(IS_ERR(dc_clk) || IS_ERR(hhc_clk)); | ||
2823 | /* can't use omap_udc_enable_clock yet */ | ||
2824 | clk_enable(dc_clk); | ||
2825 | clk_enable(hhc_clk); | ||
2826 | udelay(100); | ||
2827 | } | ||
2828 | |||
2829 | if (cpu_is_omap7xx()) { | 2793 | if (cpu_is_omap7xx()) { |
2830 | dc_clk = clk_get(&pdev->dev, "usb_dc_ck"); | 2794 | dc_clk = clk_get(&pdev->dev, "usb_dc_ck"); |
2831 | hhc_clk = clk_get(&pdev->dev, "l3_ocpi_ck"); | 2795 | hhc_clk = clk_get(&pdev->dev, "l3_ocpi_ck"); |
@@ -2875,14 +2839,6 @@ static int __init omap_udc_probe(struct platform_device *pdev) | |||
2875 | 2839 | ||
2876 | hmc = HMC_1610; | 2840 | hmc = HMC_1610; |
2877 | 2841 | ||
2878 | if (cpu_is_omap24xx()) { | ||
2879 | /* this could be transceiverless in one of the | ||
2880 | * "we don't need to know" modes. | ||
2881 | */ | ||
2882 | type = "external"; | ||
2883 | goto known; | ||
2884 | } | ||
2885 | |||
2886 | switch (hmc) { | 2842 | switch (hmc) { |
2887 | case 0: /* POWERUP DEFAULT == 0 */ | 2843 | case 0: /* POWERUP DEFAULT == 0 */ |
2888 | case 4: | 2844 | case 4: |
@@ -2921,16 +2877,16 @@ bad_on_1710: | |||
2921 | goto cleanup0; | 2877 | goto cleanup0; |
2922 | } | 2878 | } |
2923 | } | 2879 | } |
2924 | known: | 2880 | |
2925 | INFO("hmc mode %d, %s transceiver\n", hmc, type); | 2881 | INFO("hmc mode %d, %s transceiver\n", hmc, type); |
2926 | 2882 | ||
2927 | /* a "gadget" abstracts/virtualizes the controller */ | 2883 | /* a "gadget" abstracts/virtualizes the controller */ |
2928 | status = omap_udc_setup(pdev, xceiv); | 2884 | status = omap_udc_setup(pdev, xceiv); |
2929 | if (status) { | 2885 | if (status) |
2930 | goto cleanup0; | 2886 | goto cleanup0; |
2931 | } | 2887 | |
2932 | xceiv = NULL; | 2888 | xceiv = NULL; |
2933 | // "udc" is now valid | 2889 | /* "udc" is now valid */ |
2934 | pullup_disable(udc); | 2890 | pullup_disable(udc); |
2935 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 2891 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
2936 | udc->gadget.is_otg = (config->otg != 0); | 2892 | udc->gadget.is_otg = (config->otg != 0); |
@@ -2944,7 +2900,7 @@ known: | |||
2944 | 2900 | ||
2945 | /* USB general purpose IRQ: ep0, state changes, dma, etc */ | 2901 | /* USB general purpose IRQ: ep0, state changes, dma, etc */ |
2946 | status = request_irq(pdev->resource[1].start, omap_udc_irq, | 2902 | status = request_irq(pdev->resource[1].start, omap_udc_irq, |
2947 | IRQF_SAMPLE_RANDOM, driver_name, udc); | 2903 | 0, driver_name, udc); |
2948 | if (status != 0) { | 2904 | if (status != 0) { |
2949 | ERR("can't get irq %d, err %d\n", | 2905 | ERR("can't get irq %d, err %d\n", |
2950 | (int) pdev->resource[1].start, status); | 2906 | (int) pdev->resource[1].start, status); |
@@ -2953,7 +2909,7 @@ known: | |||
2953 | 2909 | ||
2954 | /* USB "non-iso" IRQ (PIO for all but ep0) */ | 2910 | /* USB "non-iso" IRQ (PIO for all but ep0) */ |
2955 | status = request_irq(pdev->resource[2].start, omap_udc_pio_irq, | 2911 | status = request_irq(pdev->resource[2].start, omap_udc_pio_irq, |
2956 | IRQF_SAMPLE_RANDOM, "omap_udc pio", udc); | 2912 | 0, "omap_udc pio", udc); |
2957 | if (status != 0) { | 2913 | if (status != 0) { |
2958 | ERR("can't get irq %d, err %d\n", | 2914 | ERR("can't get irq %d, err %d\n", |
2959 | (int) pdev->resource[2].start, status); | 2915 | (int) pdev->resource[2].start, status); |
@@ -2975,16 +2931,6 @@ known: | |||
2975 | clk_disable(dc_clk); | 2931 | clk_disable(dc_clk); |
2976 | } | 2932 | } |
2977 | 2933 | ||
2978 | if (cpu_is_omap24xx()) { | ||
2979 | udc->dc_clk = dc_clk; | ||
2980 | udc->hhc_clk = hhc_clk; | ||
2981 | /* FIXME OMAP2 don't release hhc & dc clock */ | ||
2982 | #if 0 | ||
2983 | clk_disable(hhc_clk); | ||
2984 | clk_disable(dc_clk); | ||
2985 | #endif | ||
2986 | } | ||
2987 | |||
2988 | create_proc_file(); | 2934 | create_proc_file(); |
2989 | status = device_add(&udc->gadget.dev); | 2935 | status = device_add(&udc->gadget.dev); |
2990 | if (status) | 2936 | if (status) |
@@ -3006,14 +2952,14 @@ cleanup2: | |||
3006 | free_irq(pdev->resource[1].start, udc); | 2952 | free_irq(pdev->resource[1].start, udc); |
3007 | 2953 | ||
3008 | cleanup1: | 2954 | cleanup1: |
3009 | kfree (udc); | 2955 | kfree(udc); |
3010 | udc = NULL; | 2956 | udc = NULL; |
3011 | 2957 | ||
3012 | cleanup0: | 2958 | cleanup0: |
3013 | if (xceiv) | 2959 | if (xceiv) |
3014 | usb_put_transceiver(xceiv); | 2960 | usb_put_transceiver(xceiv); |
3015 | 2961 | ||
3016 | if (cpu_is_omap16xx() || cpu_is_omap24xx() || cpu_is_omap7xx()) { | 2962 | if (cpu_is_omap16xx() || cpu_is_omap7xx()) { |
3017 | clk_disable(hhc_clk); | 2963 | clk_disable(hhc_clk); |
3018 | clk_disable(dc_clk); | 2964 | clk_disable(dc_clk); |
3019 | clk_put(hhc_clk); | 2965 | clk_put(hhc_clk); |
@@ -3026,7 +2972,7 @@ cleanup0: | |||
3026 | return status; | 2972 | return status; |
3027 | } | 2973 | } |
3028 | 2974 | ||
3029 | static int __exit omap_udc_remove(struct platform_device *pdev) | 2975 | static int __devexit omap_udc_remove(struct platform_device *pdev) |
3030 | { | 2976 | { |
3031 | DECLARE_COMPLETION_ONSTACK(done); | 2977 | DECLARE_COMPLETION_ONSTACK(done); |
3032 | 2978 | ||
@@ -3111,7 +3057,8 @@ static int omap_udc_resume(struct platform_device *dev) | |||
3111 | /*-------------------------------------------------------------------------*/ | 3057 | /*-------------------------------------------------------------------------*/ |
3112 | 3058 | ||
3113 | static struct platform_driver udc_driver = { | 3059 | static struct platform_driver udc_driver = { |
3114 | .remove = __exit_p(omap_udc_remove), | 3060 | .probe = omap_udc_probe, |
3061 | .remove = __devexit_p(omap_udc_remove), | ||
3115 | .suspend = omap_udc_suspend, | 3062 | .suspend = omap_udc_suspend, |
3116 | .resume = omap_udc_resume, | 3063 | .resume = omap_udc_resume, |
3117 | .driver = { | 3064 | .driver = { |
@@ -3120,27 +3067,7 @@ static struct platform_driver udc_driver = { | |||
3120 | }, | 3067 | }, |
3121 | }; | 3068 | }; |
3122 | 3069 | ||
3123 | static int __init udc_init(void) | 3070 | module_platform_driver(udc_driver); |
3124 | { | ||
3125 | /* Disable DMA for omap7xx -- it doesn't work right. */ | ||
3126 | if (cpu_is_omap7xx()) | ||
3127 | use_dma = 0; | ||
3128 | |||
3129 | INFO("%s, version: " DRIVER_VERSION | ||
3130 | #ifdef USE_ISO | ||
3131 | " (iso)" | ||
3132 | #endif | ||
3133 | "%s\n", driver_desc, | ||
3134 | use_dma ? " (dma)" : ""); | ||
3135 | return platform_driver_probe(&udc_driver, omap_udc_probe); | ||
3136 | } | ||
3137 | module_init(udc_init); | ||
3138 | |||
3139 | static void __exit udc_exit(void) | ||
3140 | { | ||
3141 | platform_driver_unregister(&udc_driver); | ||
3142 | } | ||
3143 | module_exit(udc_exit); | ||
3144 | 3071 | ||
3145 | MODULE_DESCRIPTION(DRIVER_DESC); | 3072 | MODULE_DESCRIPTION(DRIVER_DESC); |
3146 | MODULE_LICENSE("GPL"); | 3073 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 1cfcc9ecbfbc..f4fb71c9ae08 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c | |||
@@ -2208,7 +2208,7 @@ static void pch_udc_complete_receiver(struct pch_udc_ep *ep) | |||
2208 | return; | 2208 | return; |
2209 | } | 2209 | } |
2210 | if ((td->status & PCH_UDC_BUFF_STS) == PCH_UDC_BS_DMA_DONE) | 2210 | if ((td->status & PCH_UDC_BUFF_STS) == PCH_UDC_BS_DMA_DONE) |
2211 | if (td->status | PCH_UDC_DMA_LAST) { | 2211 | if (td->status & PCH_UDC_DMA_LAST) { |
2212 | count = td->status & PCH_UDC_RXTX_BYTES; | 2212 | count = td->status & PCH_UDC_RXTX_BYTES; |
2213 | break; | 2213 | break; |
2214 | } | 2214 | } |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index f4abb0ed9872..b13e0bb5f5b8 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -112,7 +112,6 @@ struct s3c_hsotg_ep { | |||
112 | struct s3c_hsotg_req *req; | 112 | struct s3c_hsotg_req *req; |
113 | struct dentry *debugfs; | 113 | struct dentry *debugfs; |
114 | 114 | ||
115 | spinlock_t lock; | ||
116 | 115 | ||
117 | unsigned long total_data; | 116 | unsigned long total_data; |
118 | unsigned int size_loaded; | 117 | unsigned int size_loaded; |
@@ -136,7 +135,6 @@ struct s3c_hsotg_ep { | |||
136 | * @driver: USB gadget driver | 135 | * @driver: USB gadget driver |
137 | * @plat: The platform specific configuration data. | 136 | * @plat: The platform specific configuration data. |
138 | * @regs: The memory area mapped for accessing registers. | 137 | * @regs: The memory area mapped for accessing registers. |
139 | * @regs_res: The resource that was allocated when claiming register space. | ||
140 | * @irq: The IRQ number we are using | 138 | * @irq: The IRQ number we are using |
141 | * @supplies: Definition of USB power supplies | 139 | * @supplies: Definition of USB power supplies |
142 | * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. | 140 | * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. |
@@ -157,8 +155,9 @@ struct s3c_hsotg { | |||
157 | struct usb_gadget_driver *driver; | 155 | struct usb_gadget_driver *driver; |
158 | struct s3c_hsotg_plat *plat; | 156 | struct s3c_hsotg_plat *plat; |
159 | 157 | ||
158 | spinlock_t lock; | ||
159 | |||
160 | void __iomem *regs; | 160 | void __iomem *regs; |
161 | struct resource *regs_res; | ||
162 | int irq; | 161 | int irq; |
163 | struct clk *clk; | 162 | struct clk *clk; |
164 | 163 | ||
@@ -896,7 +895,6 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
896 | struct s3c_hsotg_req *hs_req = our_req(req); | 895 | struct s3c_hsotg_req *hs_req = our_req(req); |
897 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 896 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
898 | struct s3c_hsotg *hs = hs_ep->parent; | 897 | struct s3c_hsotg *hs = hs_ep->parent; |
899 | unsigned long irqflags; | ||
900 | bool first; | 898 | bool first; |
901 | 899 | ||
902 | dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", | 900 | dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", |
@@ -915,19 +913,30 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
915 | return ret; | 913 | return ret; |
916 | } | 914 | } |
917 | 915 | ||
918 | spin_lock_irqsave(&hs_ep->lock, irqflags); | ||
919 | |||
920 | first = list_empty(&hs_ep->queue); | 916 | first = list_empty(&hs_ep->queue); |
921 | list_add_tail(&hs_req->queue, &hs_ep->queue); | 917 | list_add_tail(&hs_req->queue, &hs_ep->queue); |
922 | 918 | ||
923 | if (first) | 919 | if (first) |
924 | s3c_hsotg_start_req(hs, hs_ep, hs_req, false); | 920 | s3c_hsotg_start_req(hs, hs_ep, hs_req, false); |
925 | 921 | ||
926 | spin_unlock_irqrestore(&hs_ep->lock, irqflags); | ||
927 | |||
928 | return 0; | 922 | return 0; |
929 | } | 923 | } |
930 | 924 | ||
925 | static int s3c_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req, | ||
926 | gfp_t gfp_flags) | ||
927 | { | ||
928 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | ||
929 | struct s3c_hsotg *hs = hs_ep->parent; | ||
930 | unsigned long flags = 0; | ||
931 | int ret = 0; | ||
932 | |||
933 | spin_lock_irqsave(&hs->lock, flags); | ||
934 | ret = s3c_hsotg_ep_queue(ep, req, gfp_flags); | ||
935 | spin_unlock_irqrestore(&hs->lock, flags); | ||
936 | |||
937 | return ret; | ||
938 | } | ||
939 | |||
931 | static void s3c_hsotg_ep_free_request(struct usb_ep *ep, | 940 | static void s3c_hsotg_ep_free_request(struct usb_ep *ep, |
932 | struct usb_request *req) | 941 | struct usb_request *req) |
933 | { | 942 | { |
@@ -1383,9 +1392,9 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, | |||
1383 | */ | 1392 | */ |
1384 | 1393 | ||
1385 | if (hs_req->req.complete) { | 1394 | if (hs_req->req.complete) { |
1386 | spin_unlock(&hs_ep->lock); | 1395 | spin_unlock(&hsotg->lock); |
1387 | hs_req->req.complete(&hs_ep->ep, &hs_req->req); | 1396 | hs_req->req.complete(&hs_ep->ep, &hs_req->req); |
1388 | spin_lock(&hs_ep->lock); | 1397 | spin_lock(&hsotg->lock); |
1389 | } | 1398 | } |
1390 | 1399 | ||
1391 | /* | 1400 | /* |
@@ -1404,28 +1413,6 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, | |||
1404 | } | 1413 | } |
1405 | 1414 | ||
1406 | /** | 1415 | /** |
1407 | * s3c_hsotg_complete_request_lock - complete a request given to us (locked) | ||
1408 | * @hsotg: The device state. | ||
1409 | * @hs_ep: The endpoint the request was on. | ||
1410 | * @hs_req: The request to complete. | ||
1411 | * @result: The result code (0 => Ok, otherwise errno) | ||
1412 | * | ||
1413 | * See s3c_hsotg_complete_request(), but called with the endpoint's | ||
1414 | * lock held. | ||
1415 | */ | ||
1416 | static void s3c_hsotg_complete_request_lock(struct s3c_hsotg *hsotg, | ||
1417 | struct s3c_hsotg_ep *hs_ep, | ||
1418 | struct s3c_hsotg_req *hs_req, | ||
1419 | int result) | ||
1420 | { | ||
1421 | unsigned long flags; | ||
1422 | |||
1423 | spin_lock_irqsave(&hs_ep->lock, flags); | ||
1424 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); | ||
1425 | spin_unlock_irqrestore(&hs_ep->lock, flags); | ||
1426 | } | ||
1427 | |||
1428 | /** | ||
1429 | * s3c_hsotg_rx_data - receive data from the FIFO for an endpoint | 1416 | * s3c_hsotg_rx_data - receive data from the FIFO for an endpoint |
1430 | * @hsotg: The device state. | 1417 | * @hsotg: The device state. |
1431 | * @ep_idx: The endpoint index for the data | 1418 | * @ep_idx: The endpoint index for the data |
@@ -1444,6 +1431,7 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | |||
1444 | int max_req; | 1431 | int max_req; |
1445 | int read_ptr; | 1432 | int read_ptr; |
1446 | 1433 | ||
1434 | |||
1447 | if (!hs_req) { | 1435 | if (!hs_req) { |
1448 | u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); | 1436 | u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); |
1449 | int ptr; | 1437 | int ptr; |
@@ -1459,8 +1447,6 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | |||
1459 | return; | 1447 | return; |
1460 | } | 1448 | } |
1461 | 1449 | ||
1462 | spin_lock(&hs_ep->lock); | ||
1463 | |||
1464 | to_read = size; | 1450 | to_read = size; |
1465 | read_ptr = hs_req->req.actual; | 1451 | read_ptr = hs_req->req.actual; |
1466 | max_req = hs_req->req.length - read_ptr; | 1452 | max_req = hs_req->req.length - read_ptr; |
@@ -1487,8 +1473,6 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | |||
1487 | * alignment of the data. | 1473 | * alignment of the data. |
1488 | */ | 1474 | */ |
1489 | readsl(fifo, hs_req->req.buf + read_ptr, to_read); | 1475 | readsl(fifo, hs_req->req.buf + read_ptr, to_read); |
1490 | |||
1491 | spin_unlock(&hs_ep->lock); | ||
1492 | } | 1476 | } |
1493 | 1477 | ||
1494 | /** | 1478 | /** |
@@ -1609,7 +1593,7 @@ static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg, | |||
1609 | s3c_hsotg_send_zlp(hsotg, hs_req); | 1593 | s3c_hsotg_send_zlp(hsotg, hs_req); |
1610 | } | 1594 | } |
1611 | 1595 | ||
1612 | s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, result); | 1596 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); |
1613 | } | 1597 | } |
1614 | 1598 | ||
1615 | /** | 1599 | /** |
@@ -1864,7 +1848,7 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, | |||
1864 | /* Finish ZLP handling for IN EP0 transactions */ | 1848 | /* Finish ZLP handling for IN EP0 transactions */ |
1865 | if (hsotg->eps[0].sent_zlp) { | 1849 | if (hsotg->eps[0].sent_zlp) { |
1866 | dev_dbg(hsotg->dev, "zlp packet received\n"); | 1850 | dev_dbg(hsotg->dev, "zlp packet received\n"); |
1867 | s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, 0); | 1851 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); |
1868 | return; | 1852 | return; |
1869 | } | 1853 | } |
1870 | 1854 | ||
@@ -1915,7 +1899,7 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, | |||
1915 | dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__); | 1899 | dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__); |
1916 | s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); | 1900 | s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); |
1917 | } else | 1901 | } else |
1918 | s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, 0); | 1902 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); |
1919 | } | 1903 | } |
1920 | 1904 | ||
1921 | /** | 1905 | /** |
@@ -2123,9 +2107,6 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, | |||
2123 | int result, bool force) | 2107 | int result, bool force) |
2124 | { | 2108 | { |
2125 | struct s3c_hsotg_req *req, *treq; | 2109 | struct s3c_hsotg_req *req, *treq; |
2126 | unsigned long flags; | ||
2127 | |||
2128 | spin_lock_irqsave(&ep->lock, flags); | ||
2129 | 2110 | ||
2130 | list_for_each_entry_safe(req, treq, &ep->queue, queue) { | 2111 | list_for_each_entry_safe(req, treq, &ep->queue, queue) { |
2131 | /* | 2112 | /* |
@@ -2139,14 +2120,15 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, | |||
2139 | s3c_hsotg_complete_request(hsotg, ep, req, | 2120 | s3c_hsotg_complete_request(hsotg, ep, req, |
2140 | result); | 2121 | result); |
2141 | } | 2122 | } |
2142 | |||
2143 | spin_unlock_irqrestore(&ep->lock, flags); | ||
2144 | } | 2123 | } |
2145 | 2124 | ||
2146 | #define call_gadget(_hs, _entry) \ | 2125 | #define call_gadget(_hs, _entry) \ |
2147 | if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \ | 2126 | if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \ |
2148 | (_hs)->driver && (_hs)->driver->_entry) \ | 2127 | (_hs)->driver && (_hs)->driver->_entry) { \ |
2149 | (_hs)->driver->_entry(&(_hs)->gadget); | 2128 | spin_unlock(&_hs->lock); \ |
2129 | (_hs)->driver->_entry(&(_hs)->gadget); \ | ||
2130 | spin_lock(&_hs->lock); \ | ||
2131 | } | ||
2150 | 2132 | ||
2151 | /** | 2133 | /** |
2152 | * s3c_hsotg_disconnect - disconnect service | 2134 | * s3c_hsotg_disconnect - disconnect service |
@@ -2388,6 +2370,7 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) | |||
2388 | u32 gintsts; | 2370 | u32 gintsts; |
2389 | u32 gintmsk; | 2371 | u32 gintmsk; |
2390 | 2372 | ||
2373 | spin_lock(&hsotg->lock); | ||
2391 | irq_retry: | 2374 | irq_retry: |
2392 | gintsts = readl(hsotg->regs + GINTSTS); | 2375 | gintsts = readl(hsotg->regs + GINTSTS); |
2393 | gintmsk = readl(hsotg->regs + GINTMSK); | 2376 | gintmsk = readl(hsotg->regs + GINTMSK); |
@@ -2557,6 +2540,8 @@ irq_retry: | |||
2557 | if (gintsts & IRQ_RETRY_MASK && --retry_count > 0) | 2540 | if (gintsts & IRQ_RETRY_MASK && --retry_count > 0) |
2558 | goto irq_retry; | 2541 | goto irq_retry; |
2559 | 2542 | ||
2543 | spin_unlock(&hsotg->lock); | ||
2544 | |||
2560 | return IRQ_HANDLED; | 2545 | return IRQ_HANDLED; |
2561 | } | 2546 | } |
2562 | 2547 | ||
@@ -2604,7 +2589,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, | |||
2604 | dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n", | 2589 | dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n", |
2605 | __func__, epctrl, epctrl_reg); | 2590 | __func__, epctrl, epctrl_reg); |
2606 | 2591 | ||
2607 | spin_lock_irqsave(&hs_ep->lock, flags); | 2592 | spin_lock_irqsave(&hsotg->lock, flags); |
2608 | 2593 | ||
2609 | epctrl &= ~(DxEPCTL_EPType_MASK | DxEPCTL_MPS_MASK); | 2594 | epctrl &= ~(DxEPCTL_EPType_MASK | DxEPCTL_MPS_MASK); |
2610 | epctrl |= DxEPCTL_MPS(mps); | 2595 | epctrl |= DxEPCTL_MPS(mps); |
@@ -2683,7 +2668,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, | |||
2683 | s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); | 2668 | s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); |
2684 | 2669 | ||
2685 | out: | 2670 | out: |
2686 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2671 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2687 | return ret; | 2672 | return ret; |
2688 | } | 2673 | } |
2689 | 2674 | ||
@@ -2710,10 +2695,10 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) | |||
2710 | 2695 | ||
2711 | epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); | 2696 | epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); |
2712 | 2697 | ||
2698 | spin_lock_irqsave(&hsotg->lock, flags); | ||
2713 | /* terminate all requests with shutdown */ | 2699 | /* terminate all requests with shutdown */ |
2714 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); | 2700 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); |
2715 | 2701 | ||
2716 | spin_lock_irqsave(&hs_ep->lock, flags); | ||
2717 | 2702 | ||
2718 | ctrl = readl(hsotg->regs + epctrl_reg); | 2703 | ctrl = readl(hsotg->regs + epctrl_reg); |
2719 | ctrl &= ~DxEPCTL_EPEna; | 2704 | ctrl &= ~DxEPCTL_EPEna; |
@@ -2726,7 +2711,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) | |||
2726 | /* disable endpoint interrupts */ | 2711 | /* disable endpoint interrupts */ |
2727 | s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); | 2712 | s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); |
2728 | 2713 | ||
2729 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2714 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2730 | return 0; | 2715 | return 0; |
2731 | } | 2716 | } |
2732 | 2717 | ||
@@ -2761,15 +2746,15 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) | |||
2761 | 2746 | ||
2762 | dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); | 2747 | dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); |
2763 | 2748 | ||
2764 | spin_lock_irqsave(&hs_ep->lock, flags); | 2749 | spin_lock_irqsave(&hs->lock, flags); |
2765 | 2750 | ||
2766 | if (!on_list(hs_ep, hs_req)) { | 2751 | if (!on_list(hs_ep, hs_req)) { |
2767 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2752 | spin_unlock_irqrestore(&hs->lock, flags); |
2768 | return -EINVAL; | 2753 | return -EINVAL; |
2769 | } | 2754 | } |
2770 | 2755 | ||
2771 | s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); | 2756 | s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); |
2772 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2757 | spin_unlock_irqrestore(&hs->lock, flags); |
2773 | 2758 | ||
2774 | return 0; | 2759 | return 0; |
2775 | } | 2760 | } |
@@ -2784,15 +2769,12 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2784 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 2769 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
2785 | struct s3c_hsotg *hs = hs_ep->parent; | 2770 | struct s3c_hsotg *hs = hs_ep->parent; |
2786 | int index = hs_ep->index; | 2771 | int index = hs_ep->index; |
2787 | unsigned long irqflags; | ||
2788 | u32 epreg; | 2772 | u32 epreg; |
2789 | u32 epctl; | 2773 | u32 epctl; |
2790 | u32 xfertype; | 2774 | u32 xfertype; |
2791 | 2775 | ||
2792 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); | 2776 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); |
2793 | 2777 | ||
2794 | spin_lock_irqsave(&hs_ep->lock, irqflags); | ||
2795 | |||
2796 | /* write both IN and OUT control registers */ | 2778 | /* write both IN and OUT control registers */ |
2797 | 2779 | ||
2798 | epreg = DIEPCTL(index); | 2780 | epreg = DIEPCTL(index); |
@@ -2827,19 +2809,36 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2827 | 2809 | ||
2828 | writel(epctl, hs->regs + epreg); | 2810 | writel(epctl, hs->regs + epreg); |
2829 | 2811 | ||
2830 | spin_unlock_irqrestore(&hs_ep->lock, irqflags); | ||
2831 | |||
2832 | return 0; | 2812 | return 0; |
2833 | } | 2813 | } |
2834 | 2814 | ||
2815 | /** | ||
2816 | * s3c_hsotg_ep_sethalt_lock - set halt on a given endpoint with lock held | ||
2817 | * @ep: The endpoint to set halt. | ||
2818 | * @value: Set or unset the halt. | ||
2819 | */ | ||
2820 | static int s3c_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value) | ||
2821 | { | ||
2822 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | ||
2823 | struct s3c_hsotg *hs = hs_ep->parent; | ||
2824 | unsigned long flags = 0; | ||
2825 | int ret = 0; | ||
2826 | |||
2827 | spin_lock_irqsave(&hs->lock, flags); | ||
2828 | ret = s3c_hsotg_ep_sethalt(ep, value); | ||
2829 | spin_unlock_irqrestore(&hs->lock, flags); | ||
2830 | |||
2831 | return ret; | ||
2832 | } | ||
2833 | |||
2835 | static struct usb_ep_ops s3c_hsotg_ep_ops = { | 2834 | static struct usb_ep_ops s3c_hsotg_ep_ops = { |
2836 | .enable = s3c_hsotg_ep_enable, | 2835 | .enable = s3c_hsotg_ep_enable, |
2837 | .disable = s3c_hsotg_ep_disable, | 2836 | .disable = s3c_hsotg_ep_disable, |
2838 | .alloc_request = s3c_hsotg_ep_alloc_request, | 2837 | .alloc_request = s3c_hsotg_ep_alloc_request, |
2839 | .free_request = s3c_hsotg_ep_free_request, | 2838 | .free_request = s3c_hsotg_ep_free_request, |
2840 | .queue = s3c_hsotg_ep_queue, | 2839 | .queue = s3c_hsotg_ep_queue_lock, |
2841 | .dequeue = s3c_hsotg_ep_dequeue, | 2840 | .dequeue = s3c_hsotg_ep_dequeue, |
2842 | .set_halt = s3c_hsotg_ep_sethalt, | 2841 | .set_halt = s3c_hsotg_ep_sethalt_lock, |
2843 | /* note, don't believe we have any call for the fifo routines */ | 2842 | /* note, don't believe we have any call for the fifo routines */ |
2844 | }; | 2843 | }; |
2845 | 2844 | ||
@@ -2954,6 +2953,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, | |||
2954 | driver->driver.bus = NULL; | 2953 | driver->driver.bus = NULL; |
2955 | hsotg->driver = driver; | 2954 | hsotg->driver = driver; |
2956 | hsotg->gadget.dev.driver = &driver->driver; | 2955 | hsotg->gadget.dev.driver = &driver->driver; |
2956 | hsotg->gadget.dev.of_node = hsotg->dev->of_node; | ||
2957 | hsotg->gadget.dev.dma_mask = hsotg->dev->dma_mask; | 2957 | hsotg->gadget.dev.dma_mask = hsotg->dev->dma_mask; |
2958 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | 2958 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; |
2959 | 2959 | ||
@@ -2964,9 +2964,6 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, | |||
2964 | goto err; | 2964 | goto err; |
2965 | } | 2965 | } |
2966 | 2966 | ||
2967 | s3c_hsotg_phy_enable(hsotg); | ||
2968 | |||
2969 | s3c_hsotg_core_init(hsotg); | ||
2970 | hsotg->last_rst = jiffies; | 2967 | hsotg->last_rst = jiffies; |
2971 | dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); | 2968 | dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); |
2972 | return 0; | 2969 | return 0; |
@@ -2988,6 +2985,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, | |||
2988 | struct usb_gadget_driver *driver) | 2985 | struct usb_gadget_driver *driver) |
2989 | { | 2986 | { |
2990 | struct s3c_hsotg *hsotg = to_hsotg(gadget); | 2987 | struct s3c_hsotg *hsotg = to_hsotg(gadget); |
2988 | unsigned long flags = 0; | ||
2991 | int ep; | 2989 | int ep; |
2992 | 2990 | ||
2993 | if (!hsotg) | 2991 | if (!hsotg) |
@@ -3000,6 +2998,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, | |||
3000 | for (ep = 0; ep < hsotg->num_of_eps; ep++) | 2998 | for (ep = 0; ep < hsotg->num_of_eps; ep++) |
3001 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); | 2999 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); |
3002 | 3000 | ||
3001 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3002 | |||
3003 | s3c_hsotg_phy_disable(hsotg); | 3003 | s3c_hsotg_phy_disable(hsotg); |
3004 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | 3004 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); |
3005 | 3005 | ||
@@ -3007,6 +3007,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, | |||
3007 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | 3007 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; |
3008 | hsotg->gadget.dev.driver = NULL; | 3008 | hsotg->gadget.dev.driver = NULL; |
3009 | 3009 | ||
3010 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3011 | |||
3010 | dev_info(hsotg->dev, "unregistered gadget driver '%s'\n", | 3012 | dev_info(hsotg->dev, "unregistered gadget driver '%s'\n", |
3011 | driver->driver.name); | 3013 | driver->driver.name); |
3012 | 3014 | ||
@@ -3024,10 +3026,40 @@ static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget) | |||
3024 | return s3c_hsotg_read_frameno(to_hsotg(gadget)); | 3026 | return s3c_hsotg_read_frameno(to_hsotg(gadget)); |
3025 | } | 3027 | } |
3026 | 3028 | ||
3029 | /** | ||
3030 | * s3c_hsotg_pullup - connect/disconnect the USB PHY | ||
3031 | * @gadget: The usb gadget state | ||
3032 | * @is_on: Current state of the USB PHY | ||
3033 | * | ||
3034 | * Connect/Disconnect the USB PHY pullup | ||
3035 | */ | ||
3036 | static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) | ||
3037 | { | ||
3038 | struct s3c_hsotg *hsotg = to_hsotg(gadget); | ||
3039 | unsigned long flags = 0; | ||
3040 | |||
3041 | dev_dbg(hsotg->dev, "%s: is_in: %d\n", __func__, is_on); | ||
3042 | |||
3043 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3044 | if (is_on) { | ||
3045 | s3c_hsotg_phy_enable(hsotg); | ||
3046 | s3c_hsotg_core_init(hsotg); | ||
3047 | } else { | ||
3048 | s3c_hsotg_disconnect(hsotg); | ||
3049 | s3c_hsotg_phy_disable(hsotg); | ||
3050 | } | ||
3051 | |||
3052 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | ||
3053 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3054 | |||
3055 | return 0; | ||
3056 | } | ||
3057 | |||
3027 | static struct usb_gadget_ops s3c_hsotg_gadget_ops = { | 3058 | static struct usb_gadget_ops s3c_hsotg_gadget_ops = { |
3028 | .get_frame = s3c_hsotg_gadget_getframe, | 3059 | .get_frame = s3c_hsotg_gadget_getframe, |
3029 | .udc_start = s3c_hsotg_udc_start, | 3060 | .udc_start = s3c_hsotg_udc_start, |
3030 | .udc_stop = s3c_hsotg_udc_stop, | 3061 | .udc_stop = s3c_hsotg_udc_stop, |
3062 | .pullup = s3c_hsotg_pullup, | ||
3031 | }; | 3063 | }; |
3032 | 3064 | ||
3033 | /** | 3065 | /** |
@@ -3063,8 +3095,6 @@ static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg, | |||
3063 | INIT_LIST_HEAD(&hs_ep->queue); | 3095 | INIT_LIST_HEAD(&hs_ep->queue); |
3064 | INIT_LIST_HEAD(&hs_ep->ep.ep_list); | 3096 | INIT_LIST_HEAD(&hs_ep->ep.ep_list); |
3065 | 3097 | ||
3066 | spin_lock_init(&hs_ep->lock); | ||
3067 | |||
3068 | /* add to the list of endpoints known by the gadget driver */ | 3098 | /* add to the list of endpoints known by the gadget driver */ |
3069 | if (epnum) | 3099 | if (epnum) |
3070 | list_add_tail(&hs_ep->ep.ep_list, &hsotg->gadget.ep_list); | 3100 | list_add_tail(&hs_ep->ep.ep_list, &hsotg->gadget.ep_list); |
@@ -3342,7 +3372,7 @@ static int ep_show(struct seq_file *seq, void *v) | |||
3342 | seq_printf(seq, "request list (%p,%p):\n", | 3372 | seq_printf(seq, "request list (%p,%p):\n", |
3343 | ep->queue.next, ep->queue.prev); | 3373 | ep->queue.next, ep->queue.prev); |
3344 | 3374 | ||
3345 | spin_lock_irqsave(&ep->lock, flags); | 3375 | spin_lock_irqsave(&hsotg->lock, flags); |
3346 | 3376 | ||
3347 | list_for_each_entry(req, &ep->queue, queue) { | 3377 | list_for_each_entry(req, &ep->queue, queue) { |
3348 | if (--show_limit < 0) { | 3378 | if (--show_limit < 0) { |
@@ -3357,7 +3387,7 @@ static int ep_show(struct seq_file *seq, void *v) | |||
3357 | req->req.actual, req->req.status); | 3387 | req->req.actual, req->req.status); |
3358 | } | 3388 | } |
3359 | 3389 | ||
3360 | spin_unlock_irqrestore(&ep->lock, flags); | 3390 | spin_unlock_irqrestore(&hsotg->lock, flags); |
3361 | 3391 | ||
3362 | return 0; | 3392 | return 0; |
3363 | } | 3393 | } |
@@ -3477,7 +3507,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3477 | return -EINVAL; | 3507 | return -EINVAL; |
3478 | } | 3508 | } |
3479 | 3509 | ||
3480 | hsotg = kzalloc(sizeof(struct s3c_hsotg), GFP_KERNEL); | 3510 | hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL); |
3481 | if (!hsotg) { | 3511 | if (!hsotg) { |
3482 | dev_err(dev, "cannot get memory\n"); | 3512 | dev_err(dev, "cannot get memory\n"); |
3483 | return -ENOMEM; | 3513 | return -ENOMEM; |
@@ -3489,46 +3519,35 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3489 | hsotg->clk = clk_get(&pdev->dev, "otg"); | 3519 | hsotg->clk = clk_get(&pdev->dev, "otg"); |
3490 | if (IS_ERR(hsotg->clk)) { | 3520 | if (IS_ERR(hsotg->clk)) { |
3491 | dev_err(dev, "cannot get otg clock\n"); | 3521 | dev_err(dev, "cannot get otg clock\n"); |
3492 | ret = PTR_ERR(hsotg->clk); | 3522 | return PTR_ERR(hsotg->clk); |
3493 | goto err_mem; | ||
3494 | } | 3523 | } |
3495 | 3524 | ||
3496 | platform_set_drvdata(pdev, hsotg); | 3525 | platform_set_drvdata(pdev, hsotg); |
3497 | 3526 | ||
3498 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 3527 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
3499 | if (!res) { | ||
3500 | dev_err(dev, "cannot find register resource 0\n"); | ||
3501 | ret = -EINVAL; | ||
3502 | goto err_clk; | ||
3503 | } | ||
3504 | |||
3505 | hsotg->regs_res = request_mem_region(res->start, resource_size(res), | ||
3506 | dev_name(dev)); | ||
3507 | if (!hsotg->regs_res) { | ||
3508 | dev_err(dev, "cannot reserve registers\n"); | ||
3509 | ret = -ENOENT; | ||
3510 | goto err_clk; | ||
3511 | } | ||
3512 | 3528 | ||
3513 | hsotg->regs = ioremap(res->start, resource_size(res)); | 3529 | hsotg->regs = devm_request_and_ioremap(&pdev->dev, res); |
3514 | if (!hsotg->regs) { | 3530 | if (!hsotg->regs) { |
3515 | dev_err(dev, "cannot map registers\n"); | 3531 | dev_err(dev, "cannot map registers\n"); |
3516 | ret = -ENXIO; | 3532 | ret = -ENXIO; |
3517 | goto err_regs_res; | 3533 | goto err_clk; |
3518 | } | 3534 | } |
3519 | 3535 | ||
3520 | ret = platform_get_irq(pdev, 0); | 3536 | ret = platform_get_irq(pdev, 0); |
3521 | if (ret < 0) { | 3537 | if (ret < 0) { |
3522 | dev_err(dev, "cannot find IRQ\n"); | 3538 | dev_err(dev, "cannot find IRQ\n"); |
3523 | goto err_regs; | 3539 | goto err_clk; |
3524 | } | 3540 | } |
3525 | 3541 | ||
3542 | spin_lock_init(&hsotg->lock); | ||
3543 | |||
3526 | hsotg->irq = ret; | 3544 | hsotg->irq = ret; |
3527 | 3545 | ||
3528 | ret = request_irq(ret, s3c_hsotg_irq, 0, dev_name(dev), hsotg); | 3546 | ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0, |
3547 | dev_name(dev), hsotg); | ||
3529 | if (ret < 0) { | 3548 | if (ret < 0) { |
3530 | dev_err(dev, "cannot claim IRQ\n"); | 3549 | dev_err(dev, "cannot claim IRQ\n"); |
3531 | goto err_regs; | 3550 | goto err_clk; |
3532 | } | 3551 | } |
3533 | 3552 | ||
3534 | dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); | 3553 | dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); |
@@ -3558,7 +3577,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3558 | hsotg->supplies); | 3577 | hsotg->supplies); |
3559 | if (ret) { | 3578 | if (ret) { |
3560 | dev_err(dev, "failed to request supplies: %d\n", ret); | 3579 | dev_err(dev, "failed to request supplies: %d\n", ret); |
3561 | goto err_irq; | 3580 | goto err_clk; |
3562 | } | 3581 | } |
3563 | 3582 | ||
3564 | ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), | 3583 | ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), |
@@ -3642,19 +3661,11 @@ err_ep_mem: | |||
3642 | err_supplies: | 3661 | err_supplies: |
3643 | s3c_hsotg_phy_disable(hsotg); | 3662 | s3c_hsotg_phy_disable(hsotg); |
3644 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | 3663 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); |
3645 | err_irq: | 3664 | |
3646 | free_irq(hsotg->irq, hsotg); | ||
3647 | err_regs: | ||
3648 | iounmap(hsotg->regs); | ||
3649 | |||
3650 | err_regs_res: | ||
3651 | release_resource(hsotg->regs_res); | ||
3652 | kfree(hsotg->regs_res); | ||
3653 | err_clk: | 3665 | err_clk: |
3654 | clk_disable_unprepare(hsotg->clk); | 3666 | clk_disable_unprepare(hsotg->clk); |
3655 | clk_put(hsotg->clk); | 3667 | clk_put(hsotg->clk); |
3656 | err_mem: | 3668 | |
3657 | kfree(hsotg); | ||
3658 | return ret; | 3669 | return ret; |
3659 | } | 3670 | } |
3660 | 3671 | ||
@@ -3675,12 +3686,6 @@ static int __devexit s3c_hsotg_remove(struct platform_device *pdev) | |||
3675 | usb_gadget_unregister_driver(hsotg->driver); | 3686 | usb_gadget_unregister_driver(hsotg->driver); |
3676 | } | 3687 | } |
3677 | 3688 | ||
3678 | free_irq(hsotg->irq, hsotg); | ||
3679 | iounmap(hsotg->regs); | ||
3680 | |||
3681 | release_resource(hsotg->regs_res); | ||
3682 | kfree(hsotg->regs_res); | ||
3683 | |||
3684 | s3c_hsotg_phy_disable(hsotg); | 3689 | s3c_hsotg_phy_disable(hsotg); |
3685 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | 3690 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); |
3686 | 3691 | ||
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 8081ca3a70a2..ae8b18869b8c 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c | |||
@@ -38,12 +38,6 @@ | |||
38 | */ | 38 | */ |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * When FSG_BUFFHD_STATIC_BUFFER is defined when this file is included | ||
42 | * the fsg_buffhd structure's buf field will be an array of FSG_BUFLEN | ||
43 | * characters rather then a pointer to void. | ||
44 | */ | ||
45 | |||
46 | /* | ||
47 | * When USB_GADGET_DEBUG_FILES is defined the module param num_buffers | 41 | * When USB_GADGET_DEBUG_FILES is defined the module param num_buffers |
48 | * sets the number of pipeline buffers (length of the fsg_buffhd array). | 42 | * sets the number of pipeline buffers (length of the fsg_buffhd array). |
49 | * The valid range of num_buffers is: num >= 2 && num <= 4. | 43 | * The valid range of num_buffers is: num >= 2 && num <= 4. |
@@ -260,11 +254,7 @@ enum fsg_buffer_state { | |||
260 | }; | 254 | }; |
261 | 255 | ||
262 | struct fsg_buffhd { | 256 | struct fsg_buffhd { |
263 | #ifdef FSG_BUFFHD_STATIC_BUFFER | ||
264 | char buf[FSG_BUFLEN]; | ||
265 | #else | ||
266 | void *buf; | 257 | void *buf; |
267 | #endif | ||
268 | enum fsg_buffer_state state; | 258 | enum fsg_buffer_state state; |
269 | struct fsg_buffhd *next; | 259 | struct fsg_buffhd *next; |
270 | 260 | ||
@@ -627,6 +617,16 @@ static struct usb_gadget_strings fsg_stringtab = { | |||
627 | * the caller must own fsg->filesem for writing. | 617 | * the caller must own fsg->filesem for writing. |
628 | */ | 618 | */ |
629 | 619 | ||
620 | static void fsg_lun_close(struct fsg_lun *curlun) | ||
621 | { | ||
622 | if (curlun->filp) { | ||
623 | LDBG(curlun, "close backing file\n"); | ||
624 | fput(curlun->filp); | ||
625 | curlun->filp = NULL; | ||
626 | } | ||
627 | } | ||
628 | |||
629 | |||
630 | static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) | 630 | static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) |
631 | { | 631 | { |
632 | int ro; | 632 | int ro; |
@@ -636,6 +636,8 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) | |||
636 | loff_t size; | 636 | loff_t size; |
637 | loff_t num_sectors; | 637 | loff_t num_sectors; |
638 | loff_t min_sectors; | 638 | loff_t min_sectors; |
639 | unsigned int blkbits; | ||
640 | unsigned int blksize; | ||
639 | 641 | ||
640 | /* R/W if we can, R/O if we must */ | 642 | /* R/W if we can, R/O if we must */ |
641 | ro = curlun->initially_ro; | 643 | ro = curlun->initially_ro; |
@@ -680,17 +682,17 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) | |||
680 | } | 682 | } |
681 | 683 | ||
682 | if (curlun->cdrom) { | 684 | if (curlun->cdrom) { |
683 | curlun->blksize = 2048; | 685 | blksize = 2048; |
684 | curlun->blkbits = 11; | 686 | blkbits = 11; |
685 | } else if (inode->i_bdev) { | 687 | } else if (inode->i_bdev) { |
686 | curlun->blksize = bdev_logical_block_size(inode->i_bdev); | 688 | blksize = bdev_logical_block_size(inode->i_bdev); |
687 | curlun->blkbits = blksize_bits(curlun->blksize); | 689 | blkbits = blksize_bits(blksize); |
688 | } else { | 690 | } else { |
689 | curlun->blksize = 512; | 691 | blksize = 512; |
690 | curlun->blkbits = 9; | 692 | blkbits = 9; |
691 | } | 693 | } |
692 | 694 | ||
693 | num_sectors = size >> curlun->blkbits; /* File size in logic-block-size blocks */ | 695 | num_sectors = size >> blkbits; /* File size in logic-block-size blocks */ |
694 | min_sectors = 1; | 696 | min_sectors = 1; |
695 | if (curlun->cdrom) { | 697 | if (curlun->cdrom) { |
696 | min_sectors = 300; /* Smallest track is 300 frames */ | 698 | min_sectors = 300; /* Smallest track is 300 frames */ |
@@ -707,7 +709,12 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) | |||
707 | goto out; | 709 | goto out; |
708 | } | 710 | } |
709 | 711 | ||
712 | if (fsg_lun_is_open(curlun)) | ||
713 | fsg_lun_close(curlun); | ||
714 | |||
710 | get_file(filp); | 715 | get_file(filp); |
716 | curlun->blksize = blksize; | ||
717 | curlun->blkbits = blkbits; | ||
711 | curlun->ro = ro; | 718 | curlun->ro = ro; |
712 | curlun->filp = filp; | 719 | curlun->filp = filp; |
713 | curlun->file_length = size; | 720 | curlun->file_length = size; |
@@ -721,16 +728,6 @@ out: | |||
721 | } | 728 | } |
722 | 729 | ||
723 | 730 | ||
724 | static void fsg_lun_close(struct fsg_lun *curlun) | ||
725 | { | ||
726 | if (curlun->filp) { | ||
727 | LDBG(curlun, "close backing file\n"); | ||
728 | fput(curlun->filp); | ||
729 | curlun->filp = NULL; | ||
730 | } | ||
731 | } | ||
732 | |||
733 | |||
734 | /*-------------------------------------------------------------------------*/ | 731 | /*-------------------------------------------------------------------------*/ |
735 | 732 | ||
736 | /* | 733 | /* |
@@ -881,19 +878,17 @@ static ssize_t fsg_store_file(struct device *dev, struct device_attribute *attr, | |||
881 | if (count > 0 && buf[count-1] == '\n') | 878 | if (count > 0 && buf[count-1] == '\n') |
882 | ((char *) buf)[count-1] = 0; /* Ugh! */ | 879 | ((char *) buf)[count-1] = 0; /* Ugh! */ |
883 | 880 | ||
884 | /* Eject current medium */ | ||
885 | down_write(filesem); | ||
886 | if (fsg_lun_is_open(curlun)) { | ||
887 | fsg_lun_close(curlun); | ||
888 | curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; | ||
889 | } | ||
890 | |||
891 | /* Load new medium */ | 881 | /* Load new medium */ |
882 | down_write(filesem); | ||
892 | if (count > 0 && buf[0]) { | 883 | if (count > 0 && buf[0]) { |
884 | /* fsg_lun_open() will close existing file if any. */ | ||
893 | rc = fsg_lun_open(curlun, buf); | 885 | rc = fsg_lun_open(curlun, buf); |
894 | if (rc == 0) | 886 | if (rc == 0) |
895 | curlun->unit_attention_data = | 887 | curlun->unit_attention_data = |
896 | SS_NOT_READY_TO_READY_TRANSITION; | 888 | SS_NOT_READY_TO_READY_TRANSITION; |
889 | } else if (fsg_lun_is_open(curlun)) { | ||
890 | fsg_lun_close(curlun); | ||
891 | curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; | ||
897 | } | 892 | } |
898 | up_write(filesem); | 893 | up_write(filesem); |
899 | return (rc < 0 ? rc : count); | 894 | return (rc < 0 ? rc : count); |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 47cf48b51c9d..5b46f022d0f0 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
@@ -798,12 +798,6 @@ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], | |||
798 | 798 | ||
799 | SET_ETHTOOL_OPS(net, &ops); | 799 | SET_ETHTOOL_OPS(net, &ops); |
800 | 800 | ||
801 | /* two kinds of host-initiated state changes: | ||
802 | * - iff DATA transfer is active, carrier is "on" | ||
803 | * - tx queueing enabled if open *and* carrier is "on" | ||
804 | */ | ||
805 | netif_carrier_off(net); | ||
806 | |||
807 | dev->gadget = g; | 801 | dev->gadget = g; |
808 | SET_NETDEV_DEV(net, &g->dev); | 802 | SET_NETDEV_DEV(net, &g->dev); |
809 | SET_NETDEV_DEVTYPE(net, &gadget_type); | 803 | SET_NETDEV_DEVTYPE(net, &gadget_type); |
@@ -817,6 +811,12 @@ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], | |||
817 | INFO(dev, "HOST MAC %pM\n", dev->host_mac); | 811 | INFO(dev, "HOST MAC %pM\n", dev->host_mac); |
818 | 812 | ||
819 | the_dev = dev; | 813 | the_dev = dev; |
814 | |||
815 | /* two kinds of host-initiated state changes: | ||
816 | * - iff DATA transfer is active, carrier is "on" | ||
817 | * - tx queueing enabled if open *and* carrier is "on" | ||
818 | */ | ||
819 | netif_carrier_off(net); | ||
820 | } | 820 | } |
821 | 821 | ||
822 | return status; | 822 | return status; |
diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h index ca4e03a1c73a..93b0c1191115 100644 --- a/drivers/usb/gadget/uvc.h +++ b/drivers/usb/gadget/uvc.h | |||
@@ -153,9 +153,11 @@ struct uvc_device | |||
153 | 153 | ||
154 | /* Descriptors */ | 154 | /* Descriptors */ |
155 | struct { | 155 | struct { |
156 | const struct uvc_descriptor_header * const *control; | 156 | const struct uvc_descriptor_header * const *fs_control; |
157 | const struct uvc_descriptor_header * const *ss_control; | ||
157 | const struct uvc_descriptor_header * const *fs_streaming; | 158 | const struct uvc_descriptor_header * const *fs_streaming; |
158 | const struct uvc_descriptor_header * const *hs_streaming; | 159 | const struct uvc_descriptor_header * const *hs_streaming; |
160 | const struct uvc_descriptor_header * const *ss_streaming; | ||
159 | } desc; | 161 | } desc; |
160 | 162 | ||
161 | unsigned int control_intf; | 163 | unsigned int control_intf; |
diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c index 668fe128f2ef..120e134e805e 100644 --- a/drivers/usb/gadget/webcam.c +++ b/drivers/usb/gadget/webcam.c | |||
@@ -272,7 +272,15 @@ static const struct uvc_color_matching_descriptor uvc_color_matching = { | |||
272 | .bMatrixCoefficients = 4, | 272 | .bMatrixCoefficients = 4, |
273 | }; | 273 | }; |
274 | 274 | ||
275 | static const struct uvc_descriptor_header * const uvc_control_cls[] = { | 275 | static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = { |
276 | (const struct uvc_descriptor_header *) &uvc_control_header, | ||
277 | (const struct uvc_descriptor_header *) &uvc_camera_terminal, | ||
278 | (const struct uvc_descriptor_header *) &uvc_processing, | ||
279 | (const struct uvc_descriptor_header *) &uvc_output_terminal, | ||
280 | NULL, | ||
281 | }; | ||
282 | |||
283 | static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = { | ||
276 | (const struct uvc_descriptor_header *) &uvc_control_header, | 284 | (const struct uvc_descriptor_header *) &uvc_control_header, |
277 | (const struct uvc_descriptor_header *) &uvc_camera_terminal, | 285 | (const struct uvc_descriptor_header *) &uvc_camera_terminal, |
278 | (const struct uvc_descriptor_header *) &uvc_processing, | 286 | (const struct uvc_descriptor_header *) &uvc_processing, |
@@ -304,6 +312,18 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = { | |||
304 | NULL, | 312 | NULL, |
305 | }; | 313 | }; |
306 | 314 | ||
315 | static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = { | ||
316 | (const struct uvc_descriptor_header *) &uvc_input_header, | ||
317 | (const struct uvc_descriptor_header *) &uvc_format_yuv, | ||
318 | (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, | ||
319 | (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, | ||
320 | (const struct uvc_descriptor_header *) &uvc_format_mjpg, | ||
321 | (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, | ||
322 | (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, | ||
323 | (const struct uvc_descriptor_header *) &uvc_color_matching, | ||
324 | NULL, | ||
325 | }; | ||
326 | |||
307 | /* -------------------------------------------------------------------------- | 327 | /* -------------------------------------------------------------------------- |
308 | * USB configuration | 328 | * USB configuration |
309 | */ | 329 | */ |
@@ -311,8 +331,9 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = { | |||
311 | static int __init | 331 | static int __init |
312 | webcam_config_bind(struct usb_configuration *c) | 332 | webcam_config_bind(struct usb_configuration *c) |
313 | { | 333 | { |
314 | return uvc_bind_config(c, uvc_control_cls, uvc_fs_streaming_cls, | 334 | return uvc_bind_config(c, uvc_fs_control_cls, uvc_ss_control_cls, |
315 | uvc_hs_streaming_cls); | 335 | uvc_fs_streaming_cls, uvc_hs_streaming_cls, |
336 | uvc_ss_streaming_cls); | ||
316 | } | 337 | } |
317 | 338 | ||
318 | static struct usb_configuration webcam_config_driver = { | 339 | static struct usb_configuration webcam_config_driver = { |
@@ -373,7 +394,7 @@ static struct usb_composite_driver webcam_driver = { | |||
373 | .name = "g_webcam", | 394 | .name = "g_webcam", |
374 | .dev = &webcam_device_descriptor, | 395 | .dev = &webcam_device_descriptor, |
375 | .strings = webcam_device_strings, | 396 | .strings = webcam_device_strings, |
376 | .max_speed = USB_SPEED_HIGH, | 397 | .max_speed = USB_SPEED_SUPER, |
377 | .unbind = webcam_unbind, | 398 | .unbind = webcam_unbind, |
378 | }; | 399 | }; |
379 | 400 | ||