diff options
Diffstat (limited to 'drivers/usb/gadget')
57 files changed, 5691 insertions, 563 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index c4880fc0d86e..747ef53bda14 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -190,6 +190,12 @@ config USB_F_UAC2 | |||
190 | config USB_F_UVC | 190 | config USB_F_UVC |
191 | tristate | 191 | tristate |
192 | 192 | ||
193 | config USB_F_MIDI | ||
194 | tristate | ||
195 | |||
196 | config USB_F_HID | ||
197 | tristate | ||
198 | |||
193 | choice | 199 | choice |
194 | tristate "USB Gadget Drivers" | 200 | tristate "USB Gadget Drivers" |
195 | default USB_ETH | 201 | default USB_ETH |
@@ -362,6 +368,61 @@ config USB_CONFIGFS_F_FS | |||
362 | implemented in kernel space (for instance Ethernet, serial or | 368 | implemented in kernel space (for instance Ethernet, serial or |
363 | mass storage) and other are implemented in user space. | 369 | mass storage) and other are implemented in user space. |
364 | 370 | ||
371 | config USB_CONFIGFS_F_UAC1 | ||
372 | boolean "Audio Class 1.0" | ||
373 | depends on USB_CONFIGFS | ||
374 | depends on SND | ||
375 | select USB_LIBCOMPOSITE | ||
376 | select SND_PCM | ||
377 | select USB_F_UAC1 | ||
378 | help | ||
379 | This Audio function implements 1 AudioControl interface, | ||
380 | 1 AudioStreaming Interface each for USB-OUT and USB-IN. | ||
381 | This driver requires a real Audio codec to be present | ||
382 | on the device. | ||
383 | |||
384 | config USB_CONFIGFS_F_UAC2 | ||
385 | boolean "Audio Class 2.0" | ||
386 | depends on USB_CONFIGFS | ||
387 | depends on SND | ||
388 | select USB_LIBCOMPOSITE | ||
389 | select SND_PCM | ||
390 | select USB_F_UAC2 | ||
391 | help | ||
392 | This Audio function is compatible with USB Audio Class | ||
393 | specification 2.0. It implements 1 AudioControl interface, | ||
394 | 1 AudioStreaming Interface each for USB-OUT and USB-IN. | ||
395 | This driver doesn't expect any real Audio codec to be present | ||
396 | on the device - the audio streams are simply sinked to and | ||
397 | sourced from a virtual ALSA sound card created. The user-space | ||
398 | application may choose to do whatever it wants with the data | ||
399 | received from the USB Host and choose to provide whatever it | ||
400 | wants as audio data to the USB Host. | ||
401 | |||
402 | config USB_CONFIGFS_F_MIDI | ||
403 | boolean "MIDI function" | ||
404 | depends on USB_CONFIGFS | ||
405 | depends on SND | ||
406 | select USB_LIBCOMPOSITE | ||
407 | select SND_RAWMIDI | ||
408 | select USB_F_MIDI | ||
409 | help | ||
410 | The MIDI Function acts as a USB Audio device, with one MIDI | ||
411 | input and one MIDI output. These MIDI jacks appear as | ||
412 | a sound "card" in the ALSA sound system. Other MIDI | ||
413 | connections can then be made on the gadget system, using | ||
414 | ALSA's aconnect utility etc. | ||
415 | |||
416 | config USB_CONFIGFS_F_HID | ||
417 | boolean "HID function" | ||
418 | depends on USB_CONFIGFS | ||
419 | select USB_F_HID | ||
420 | help | ||
421 | The HID function driver provides generic emulation of USB | ||
422 | Human Interface Devices (HID). | ||
423 | |||
424 | For more information, see Documentation/usb/gadget_hid.txt. | ||
425 | |||
365 | source "drivers/usb/gadget/legacy/Kconfig" | 426 | source "drivers/usb/gadget/legacy/Kconfig" |
366 | 427 | ||
367 | endchoice | 428 | endchoice |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f6a51fddd5b5..617835348569 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -1246,10 +1246,49 @@ EXPORT_SYMBOL_GPL(usb_string_ids_n); | |||
1246 | 1246 | ||
1247 | static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) | 1247 | static void composite_setup_complete(struct usb_ep *ep, struct usb_request *req) |
1248 | { | 1248 | { |
1249 | struct usb_composite_dev *cdev; | ||
1250 | |||
1249 | if (req->status || req->actual != req->length) | 1251 | if (req->status || req->actual != req->length) |
1250 | DBG((struct usb_composite_dev *) ep->driver_data, | 1252 | DBG((struct usb_composite_dev *) ep->driver_data, |
1251 | "setup complete --> %d, %d/%d\n", | 1253 | "setup complete --> %d, %d/%d\n", |
1252 | req->status, req->actual, req->length); | 1254 | req->status, req->actual, req->length); |
1255 | |||
1256 | /* | ||
1257 | * REVIST The same ep0 requests are shared with function drivers | ||
1258 | * so they don't have to maintain the same ->complete() stubs. | ||
1259 | * | ||
1260 | * Because of that, we need to check for the validity of ->context | ||
1261 | * here, even though we know we've set it to something useful. | ||
1262 | */ | ||
1263 | if (!req->context) | ||
1264 | return; | ||
1265 | |||
1266 | cdev = req->context; | ||
1267 | |||
1268 | if (cdev->req == req) | ||
1269 | cdev->setup_pending = false; | ||
1270 | else if (cdev->os_desc_req == req) | ||
1271 | cdev->os_desc_pending = false; | ||
1272 | else | ||
1273 | WARN(1, "unknown request %p\n", req); | ||
1274 | } | ||
1275 | |||
1276 | static int composite_ep0_queue(struct usb_composite_dev *cdev, | ||
1277 | struct usb_request *req, gfp_t gfp_flags) | ||
1278 | { | ||
1279 | int ret; | ||
1280 | |||
1281 | ret = usb_ep_queue(cdev->gadget->ep0, req, gfp_flags); | ||
1282 | if (ret == 0) { | ||
1283 | if (cdev->req == req) | ||
1284 | cdev->setup_pending = true; | ||
1285 | else if (cdev->os_desc_req == req) | ||
1286 | cdev->os_desc_pending = true; | ||
1287 | else | ||
1288 | WARN(1, "unknown request %p\n", req); | ||
1289 | } | ||
1290 | |||
1291 | return ret; | ||
1253 | } | 1292 | } |
1254 | 1293 | ||
1255 | static int count_ext_compat(struct usb_configuration *c) | 1294 | static int count_ext_compat(struct usb_configuration *c) |
@@ -1428,6 +1467,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1428 | * when we delegate to it. | 1467 | * when we delegate to it. |
1429 | */ | 1468 | */ |
1430 | req->zero = 0; | 1469 | req->zero = 0; |
1470 | req->context = cdev; | ||
1431 | req->complete = composite_setup_complete; | 1471 | req->complete = composite_setup_complete; |
1432 | req->length = 0; | 1472 | req->length = 0; |
1433 | gadget->ep0->driver_data = cdev; | 1473 | gadget->ep0->driver_data = cdev; |
@@ -1624,6 +1664,7 @@ unknown: | |||
1624 | int count = 0; | 1664 | int count = 0; |
1625 | 1665 | ||
1626 | req = cdev->os_desc_req; | 1666 | req = cdev->os_desc_req; |
1667 | req->context = cdev; | ||
1627 | req->complete = composite_setup_complete; | 1668 | req->complete = composite_setup_complete; |
1628 | buf = req->buf; | 1669 | buf = req->buf; |
1629 | os_desc_cfg = cdev->os_desc_config; | 1670 | os_desc_cfg = cdev->os_desc_config; |
@@ -1686,8 +1727,9 @@ unknown: | |||
1686 | break; | 1727 | break; |
1687 | } | 1728 | } |
1688 | req->length = value; | 1729 | req->length = value; |
1730 | req->context = cdev; | ||
1689 | req->zero = value < w_length; | 1731 | req->zero = value < w_length; |
1690 | value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); | 1732 | value = composite_ep0_queue(cdev, req, GFP_ATOMIC); |
1691 | if (value < 0) { | 1733 | if (value < 0) { |
1692 | DBG(cdev, "ep_queue --> %d\n", value); | 1734 | DBG(cdev, "ep_queue --> %d\n", value); |
1693 | req->status = 0; | 1735 | req->status = 0; |
@@ -1757,8 +1799,9 @@ unknown: | |||
1757 | /* respond with data transfer before status phase? */ | 1799 | /* respond with data transfer before status phase? */ |
1758 | if (value >= 0 && value != USB_GADGET_DELAYED_STATUS) { | 1800 | if (value >= 0 && value != USB_GADGET_DELAYED_STATUS) { |
1759 | req->length = value; | 1801 | req->length = value; |
1802 | req->context = cdev; | ||
1760 | req->zero = value < w_length; | 1803 | req->zero = value < w_length; |
1761 | value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); | 1804 | value = composite_ep0_queue(cdev, req, GFP_ATOMIC); |
1762 | if (value < 0) { | 1805 | if (value < 0) { |
1763 | DBG(cdev, "ep_queue --> %d\n", value); | 1806 | DBG(cdev, "ep_queue --> %d\n", value); |
1764 | req->status = 0; | 1807 | req->status = 0; |
@@ -1893,6 +1936,7 @@ int composite_dev_prepare(struct usb_composite_driver *composite, | |||
1893 | goto fail_dev; | 1936 | goto fail_dev; |
1894 | 1937 | ||
1895 | cdev->req->complete = composite_setup_complete; | 1938 | cdev->req->complete = composite_setup_complete; |
1939 | cdev->req->context = cdev; | ||
1896 | gadget->ep0->driver_data = cdev; | 1940 | gadget->ep0->driver_data = cdev; |
1897 | 1941 | ||
1898 | cdev->driver = composite; | 1942 | cdev->driver = composite; |
@@ -1937,6 +1981,7 @@ int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, | |||
1937 | kfree(cdev->os_desc_req); | 1981 | kfree(cdev->os_desc_req); |
1938 | goto end; | 1982 | goto end; |
1939 | } | 1983 | } |
1984 | cdev->os_desc_req->context = cdev; | ||
1940 | cdev->os_desc_req->complete = composite_setup_complete; | 1985 | cdev->os_desc_req->complete = composite_setup_complete; |
1941 | end: | 1986 | end: |
1942 | return ret; | 1987 | return ret; |
@@ -1951,10 +1996,16 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) | |||
1951 | kfree(uc); | 1996 | kfree(uc); |
1952 | } | 1997 | } |
1953 | if (cdev->os_desc_req) { | 1998 | if (cdev->os_desc_req) { |
1999 | if (cdev->os_desc_pending) | ||
2000 | usb_ep_dequeue(cdev->gadget->ep0, cdev->os_desc_req); | ||
2001 | |||
1954 | kfree(cdev->os_desc_req->buf); | 2002 | kfree(cdev->os_desc_req->buf); |
1955 | usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req); | 2003 | usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req); |
1956 | } | 2004 | } |
1957 | if (cdev->req) { | 2005 | if (cdev->req) { |
2006 | if (cdev->setup_pending) | ||
2007 | usb_ep_dequeue(cdev->gadget->ep0, cdev->req); | ||
2008 | |||
1958 | kfree(cdev->req->buf); | 2009 | kfree(cdev->req->buf); |
1959 | usb_ep_free_request(cdev->gadget->ep0, cdev->req); | 2010 | usb_ep_free_request(cdev->gadget->ep0, cdev->req); |
1960 | } | 2011 | } |
@@ -2013,8 +2064,7 @@ fail: | |||
2013 | 2064 | ||
2014 | /*-------------------------------------------------------------------------*/ | 2065 | /*-------------------------------------------------------------------------*/ |
2015 | 2066 | ||
2016 | static void | 2067 | void composite_suspend(struct usb_gadget *gadget) |
2017 | composite_suspend(struct usb_gadget *gadget) | ||
2018 | { | 2068 | { |
2019 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 2069 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
2020 | struct usb_function *f; | 2070 | struct usb_function *f; |
@@ -2037,8 +2087,7 @@ composite_suspend(struct usb_gadget *gadget) | |||
2037 | usb_gadget_vbus_draw(gadget, 2); | 2087 | usb_gadget_vbus_draw(gadget, 2); |
2038 | } | 2088 | } |
2039 | 2089 | ||
2040 | static void | 2090 | void composite_resume(struct usb_gadget *gadget) |
2041 | composite_resume(struct usb_gadget *gadget) | ||
2042 | { | 2091 | { |
2043 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 2092 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
2044 | struct usb_function *f; | 2093 | struct usb_function *f; |
@@ -2158,7 +2207,8 @@ void usb_composite_setup_continue(struct usb_composite_dev *cdev) | |||
2158 | } else if (--cdev->delayed_status == 0) { | 2207 | } else if (--cdev->delayed_status == 0) { |
2159 | DBG(cdev, "%s: Completing delayed status\n", __func__); | 2208 | DBG(cdev, "%s: Completing delayed status\n", __func__); |
2160 | req->length = 0; | 2209 | req->length = 0; |
2161 | value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); | 2210 | req->context = cdev; |
2211 | value = composite_ep0_queue(cdev, req, GFP_ATOMIC); | ||
2162 | if (value < 0) { | 2212 | if (value < 0) { |
2163 | DBG(cdev, "ep_queue --> %d\n", value); | 2213 | DBG(cdev, "ep_queue --> %d\n", value); |
2164 | req->status = 0; | 2214 | req->status = 0; |
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 34034333f7f6..75648145dc1b 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c | |||
@@ -271,7 +271,7 @@ static ssize_t gadget_dev_desc_UDC_store(struct gadget_info *gi, | |||
271 | ret = -EBUSY; | 271 | ret = -EBUSY; |
272 | goto err; | 272 | goto err; |
273 | } | 273 | } |
274 | ret = udc_attach_driver(name, &gi->composite.gadget_driver); | 274 | ret = usb_udc_attach_driver(name, &gi->composite.gadget_driver); |
275 | if (ret) | 275 | if (ret) |
276 | goto err; | 276 | goto err; |
277 | gi->udc_name = name; | 277 | gi->udc_name = name; |
@@ -1453,6 +1453,9 @@ static const struct usb_gadget_driver configfs_driver_template = { | |||
1453 | .reset = composite_disconnect, | 1453 | .reset = composite_disconnect, |
1454 | .disconnect = composite_disconnect, | 1454 | .disconnect = composite_disconnect, |
1455 | 1455 | ||
1456 | .suspend = composite_suspend, | ||
1457 | .resume = composite_resume, | ||
1458 | |||
1456 | .max_speed = USB_SPEED_SUPER, | 1459 | .max_speed = USB_SPEED_SUPER, |
1457 | .driver = { | 1460 | .driver = { |
1458 | .owner = THIS_MODULE, | 1461 | .owner = THIS_MODULE, |
diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 90701aa5a826..dd68091d92f0 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile | |||
@@ -38,3 +38,7 @@ usb_f_uac2-y := f_uac2.o | |||
38 | obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o | 38 | obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o |
39 | usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o | 39 | usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o |
40 | obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o | 40 | obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o |
41 | usb_f_midi-y := f_midi.o | ||
42 | obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o | ||
43 | usb_f_hid-y := f_hid.o | ||
44 | obj-$(CONFIG_USB_F_HID) += usb_f_hid.o | ||
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 59ab62c92b66..488ac66aae9e 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/hid.h> | 14 | #include <linux/hid.h> |
15 | #include <linux/idr.h> | ||
15 | #include <linux/cdev.h> | 16 | #include <linux/cdev.h> |
16 | #include <linux/mutex.h> | 17 | #include <linux/mutex.h> |
17 | #include <linux/poll.h> | 18 | #include <linux/poll.h> |
@@ -21,9 +22,14 @@ | |||
21 | #include <linux/usb/g_hid.h> | 22 | #include <linux/usb/g_hid.h> |
22 | 23 | ||
23 | #include "u_f.h" | 24 | #include "u_f.h" |
25 | #include "u_hid.h" | ||
26 | |||
27 | #define HIDG_MINORS 4 | ||
24 | 28 | ||
25 | static int major, minors; | 29 | static int major, minors; |
26 | static struct class *hidg_class; | 30 | static struct class *hidg_class; |
31 | static DEFINE_IDA(hidg_ida); | ||
32 | static DEFINE_MUTEX(hidg_ida_lock); /* protects access to hidg_ida */ | ||
27 | 33 | ||
28 | /*-------------------------------------------------------------------------*/ | 34 | /*-------------------------------------------------------------------------*/ |
29 | /* HID gadget struct */ | 35 | /* HID gadget struct */ |
@@ -161,6 +167,26 @@ static struct usb_descriptor_header *hidg_fs_descriptors[] = { | |||
161 | }; | 167 | }; |
162 | 168 | ||
163 | /*-------------------------------------------------------------------------*/ | 169 | /*-------------------------------------------------------------------------*/ |
170 | /* Strings */ | ||
171 | |||
172 | #define CT_FUNC_HID_IDX 0 | ||
173 | |||
174 | static struct usb_string ct_func_string_defs[] = { | ||
175 | [CT_FUNC_HID_IDX].s = "HID Interface", | ||
176 | {}, /* end of list */ | ||
177 | }; | ||
178 | |||
179 | static struct usb_gadget_strings ct_func_string_table = { | ||
180 | .language = 0x0409, /* en-US */ | ||
181 | .strings = ct_func_string_defs, | ||
182 | }; | ||
183 | |||
184 | static struct usb_gadget_strings *ct_func_strings[] = { | ||
185 | &ct_func_string_table, | ||
186 | NULL, | ||
187 | }; | ||
188 | |||
189 | /*-------------------------------------------------------------------------*/ | ||
164 | /* Char Device */ | 190 | /* Char Device */ |
165 | 191 | ||
166 | static ssize_t f_hidg_read(struct file *file, char __user *buffer, | 192 | static ssize_t f_hidg_read(struct file *file, char __user *buffer, |
@@ -552,13 +578,22 @@ const struct file_operations f_hidg_fops = { | |||
552 | .llseek = noop_llseek, | 578 | .llseek = noop_llseek, |
553 | }; | 579 | }; |
554 | 580 | ||
555 | static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) | 581 | static int hidg_bind(struct usb_configuration *c, struct usb_function *f) |
556 | { | 582 | { |
557 | struct usb_ep *ep; | 583 | struct usb_ep *ep; |
558 | struct f_hidg *hidg = func_to_hidg(f); | 584 | struct f_hidg *hidg = func_to_hidg(f); |
585 | struct usb_string *us; | ||
586 | struct device *device; | ||
559 | int status; | 587 | int status; |
560 | dev_t dev; | 588 | dev_t dev; |
561 | 589 | ||
590 | /* maybe allocate device-global string IDs, and patch descriptors */ | ||
591 | us = usb_gstrings_attach(c->cdev, ct_func_strings, | ||
592 | ARRAY_SIZE(ct_func_string_defs)); | ||
593 | if (IS_ERR(us)) | ||
594 | return PTR_ERR(us); | ||
595 | hidg_interface_desc.iInterface = us[CT_FUNC_HID_IDX].id; | ||
596 | |||
562 | /* allocate instance-specific interface IDs, and patch descriptors */ | 597 | /* allocate instance-specific interface IDs, and patch descriptors */ |
563 | status = usb_interface_id(c, f); | 598 | status = usb_interface_id(c, f); |
564 | if (status < 0) | 599 | if (status < 0) |
@@ -623,10 +658,16 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) | |||
623 | if (status) | 658 | if (status) |
624 | goto fail_free_descs; | 659 | goto fail_free_descs; |
625 | 660 | ||
626 | device_create(hidg_class, NULL, dev, NULL, "%s%d", "hidg", hidg->minor); | 661 | device = device_create(hidg_class, NULL, dev, NULL, |
662 | "%s%d", "hidg", hidg->minor); | ||
663 | if (IS_ERR(device)) { | ||
664 | status = PTR_ERR(device); | ||
665 | goto del; | ||
666 | } | ||
627 | 667 | ||
628 | return 0; | 668 | return 0; |
629 | 669 | del: | |
670 | cdev_del(&hidg->cdev); | ||
630 | fail_free_descs: | 671 | fail_free_descs: |
631 | usb_free_all_descriptors(f); | 672 | usb_free_all_descriptors(f); |
632 | fail: | 673 | fail: |
@@ -640,116 +681,313 @@ fail: | |||
640 | return status; | 681 | return status; |
641 | } | 682 | } |
642 | 683 | ||
643 | static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) | 684 | static inline int hidg_get_minor(void) |
644 | { | 685 | { |
645 | struct f_hidg *hidg = func_to_hidg(f); | 686 | int ret; |
646 | 687 | ||
647 | device_destroy(hidg_class, MKDEV(major, hidg->minor)); | 688 | ret = ida_simple_get(&hidg_ida, 0, 0, GFP_KERNEL); |
648 | cdev_del(&hidg->cdev); | ||
649 | 689 | ||
650 | /* disable/free request and end point */ | 690 | return ret; |
651 | usb_ep_disable(hidg->in_ep); | 691 | } |
652 | usb_ep_dequeue(hidg->in_ep, hidg->req); | ||
653 | kfree(hidg->req->buf); | ||
654 | usb_ep_free_request(hidg->in_ep, hidg->req); | ||
655 | |||
656 | usb_free_all_descriptors(f); | ||
657 | 692 | ||
658 | kfree(hidg->report_desc); | 693 | static inline struct f_hid_opts *to_f_hid_opts(struct config_item *item) |
659 | kfree(hidg); | 694 | { |
695 | return container_of(to_config_group(item), struct f_hid_opts, | ||
696 | func_inst.group); | ||
660 | } | 697 | } |
661 | 698 | ||
662 | /*-------------------------------------------------------------------------*/ | 699 | CONFIGFS_ATTR_STRUCT(f_hid_opts); |
663 | /* Strings */ | 700 | CONFIGFS_ATTR_OPS(f_hid_opts); |
664 | 701 | ||
665 | #define CT_FUNC_HID_IDX 0 | 702 | static void hid_attr_release(struct config_item *item) |
703 | { | ||
704 | struct f_hid_opts *opts = to_f_hid_opts(item); | ||
666 | 705 | ||
667 | static struct usb_string ct_func_string_defs[] = { | 706 | usb_put_function_instance(&opts->func_inst); |
668 | [CT_FUNC_HID_IDX].s = "HID Interface", | 707 | } |
669 | {}, /* end of list */ | ||
670 | }; | ||
671 | 708 | ||
672 | static struct usb_gadget_strings ct_func_string_table = { | 709 | static struct configfs_item_operations hidg_item_ops = { |
673 | .language = 0x0409, /* en-US */ | 710 | .release = hid_attr_release, |
674 | .strings = ct_func_string_defs, | 711 | .show_attribute = f_hid_opts_attr_show, |
712 | .store_attribute = f_hid_opts_attr_store, | ||
675 | }; | 713 | }; |
676 | 714 | ||
677 | static struct usb_gadget_strings *ct_func_strings[] = { | 715 | #define F_HID_OPT(name, prec, limit) \ |
678 | &ct_func_string_table, | 716 | static ssize_t f_hid_opts_##name##_show(struct f_hid_opts *opts, char *page)\ |
717 | { \ | ||
718 | int result; \ | ||
719 | \ | ||
720 | mutex_lock(&opts->lock); \ | ||
721 | result = sprintf(page, "%d\n", opts->name); \ | ||
722 | mutex_unlock(&opts->lock); \ | ||
723 | \ | ||
724 | return result; \ | ||
725 | } \ | ||
726 | \ | ||
727 | static ssize_t f_hid_opts_##name##_store(struct f_hid_opts *opts, \ | ||
728 | const char *page, size_t len) \ | ||
729 | { \ | ||
730 | int ret; \ | ||
731 | u##prec num; \ | ||
732 | \ | ||
733 | mutex_lock(&opts->lock); \ | ||
734 | if (opts->refcnt) { \ | ||
735 | ret = -EBUSY; \ | ||
736 | goto end; \ | ||
737 | } \ | ||
738 | \ | ||
739 | ret = kstrtou##prec(page, 0, &num); \ | ||
740 | if (ret) \ | ||
741 | goto end; \ | ||
742 | \ | ||
743 | if (num > limit) { \ | ||
744 | ret = -EINVAL; \ | ||
745 | goto end; \ | ||
746 | } \ | ||
747 | opts->name = num; \ | ||
748 | ret = len; \ | ||
749 | \ | ||
750 | end: \ | ||
751 | mutex_unlock(&opts->lock); \ | ||
752 | return ret; \ | ||
753 | } \ | ||
754 | \ | ||
755 | static struct f_hid_opts_attribute f_hid_opts_##name = \ | ||
756 | __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, f_hid_opts_##name##_show,\ | ||
757 | f_hid_opts_##name##_store) | ||
758 | |||
759 | F_HID_OPT(subclass, 8, 255); | ||
760 | F_HID_OPT(protocol, 8, 255); | ||
761 | F_HID_OPT(report_length, 16, 65536); | ||
762 | |||
763 | static ssize_t f_hid_opts_report_desc_show(struct f_hid_opts *opts, char *page) | ||
764 | { | ||
765 | int result; | ||
766 | |||
767 | mutex_lock(&opts->lock); | ||
768 | result = opts->report_desc_length; | ||
769 | memcpy(page, opts->report_desc, opts->report_desc_length); | ||
770 | mutex_unlock(&opts->lock); | ||
771 | |||
772 | return result; | ||
773 | } | ||
774 | |||
775 | static ssize_t f_hid_opts_report_desc_store(struct f_hid_opts *opts, | ||
776 | const char *page, size_t len) | ||
777 | { | ||
778 | int ret = -EBUSY; | ||
779 | char *d; | ||
780 | |||
781 | mutex_lock(&opts->lock); | ||
782 | |||
783 | if (opts->refcnt) | ||
784 | goto end; | ||
785 | if (len > PAGE_SIZE) { | ||
786 | ret = -ENOSPC; | ||
787 | goto end; | ||
788 | } | ||
789 | d = kmemdup(page, len, GFP_KERNEL); | ||
790 | if (!d) { | ||
791 | ret = -ENOMEM; | ||
792 | goto end; | ||
793 | } | ||
794 | kfree(opts->report_desc); | ||
795 | opts->report_desc = d; | ||
796 | opts->report_desc_length = len; | ||
797 | opts->report_desc_alloc = true; | ||
798 | ret = len; | ||
799 | end: | ||
800 | mutex_unlock(&opts->lock); | ||
801 | return ret; | ||
802 | } | ||
803 | |||
804 | static struct f_hid_opts_attribute f_hid_opts_report_desc = | ||
805 | __CONFIGFS_ATTR(report_desc, S_IRUGO | S_IWUSR, | ||
806 | f_hid_opts_report_desc_show, | ||
807 | f_hid_opts_report_desc_store); | ||
808 | |||
809 | static struct configfs_attribute *hid_attrs[] = { | ||
810 | &f_hid_opts_subclass.attr, | ||
811 | &f_hid_opts_protocol.attr, | ||
812 | &f_hid_opts_report_length.attr, | ||
813 | &f_hid_opts_report_desc.attr, | ||
679 | NULL, | 814 | NULL, |
680 | }; | 815 | }; |
681 | 816 | ||
682 | /*-------------------------------------------------------------------------*/ | 817 | static struct config_item_type hid_func_type = { |
683 | /* usb_configuration */ | 818 | .ct_item_ops = &hidg_item_ops, |
819 | .ct_attrs = hid_attrs, | ||
820 | .ct_owner = THIS_MODULE, | ||
821 | }; | ||
684 | 822 | ||
685 | int __init hidg_bind_config(struct usb_configuration *c, | 823 | static inline void hidg_put_minor(int minor) |
686 | struct hidg_func_descriptor *fdesc, int index) | ||
687 | { | 824 | { |
688 | struct f_hidg *hidg; | 825 | ida_simple_remove(&hidg_ida, minor); |
689 | int status; | 826 | } |
690 | 827 | ||
691 | if (index >= minors) | 828 | static void hidg_free_inst(struct usb_function_instance *f) |
692 | return -ENOENT; | 829 | { |
830 | struct f_hid_opts *opts; | ||
693 | 831 | ||
694 | /* maybe allocate device-global string IDs, and patch descriptors */ | 832 | opts = container_of(f, struct f_hid_opts, func_inst); |
695 | if (ct_func_string_defs[CT_FUNC_HID_IDX].id == 0) { | 833 | |
696 | status = usb_string_id(c->cdev); | 834 | mutex_lock(&hidg_ida_lock); |
697 | if (status < 0) | 835 | |
698 | return status; | 836 | hidg_put_minor(opts->minor); |
699 | ct_func_string_defs[CT_FUNC_HID_IDX].id = status; | 837 | if (idr_is_empty(&hidg_ida.idr)) |
700 | hidg_interface_desc.iInterface = status; | 838 | ghid_cleanup(); |
839 | |||
840 | mutex_unlock(&hidg_ida_lock); | ||
841 | |||
842 | if (opts->report_desc_alloc) | ||
843 | kfree(opts->report_desc); | ||
844 | |||
845 | kfree(opts); | ||
846 | } | ||
847 | |||
848 | static struct usb_function_instance *hidg_alloc_inst(void) | ||
849 | { | ||
850 | struct f_hid_opts *opts; | ||
851 | struct usb_function_instance *ret; | ||
852 | int status = 0; | ||
853 | |||
854 | opts = kzalloc(sizeof(*opts), GFP_KERNEL); | ||
855 | if (!opts) | ||
856 | return ERR_PTR(-ENOMEM); | ||
857 | mutex_init(&opts->lock); | ||
858 | opts->func_inst.free_func_inst = hidg_free_inst; | ||
859 | ret = &opts->func_inst; | ||
860 | |||
861 | mutex_lock(&hidg_ida_lock); | ||
862 | |||
863 | if (idr_is_empty(&hidg_ida.idr)) { | ||
864 | status = ghid_setup(NULL, HIDG_MINORS); | ||
865 | if (status) { | ||
866 | ret = ERR_PTR(status); | ||
867 | kfree(opts); | ||
868 | goto unlock; | ||
869 | } | ||
870 | } | ||
871 | |||
872 | opts->minor = hidg_get_minor(); | ||
873 | if (opts->minor < 0) { | ||
874 | ret = ERR_PTR(opts->minor); | ||
875 | kfree(opts); | ||
876 | if (idr_is_empty(&hidg_ida.idr)) | ||
877 | ghid_cleanup(); | ||
878 | goto unlock; | ||
701 | } | 879 | } |
880 | config_group_init_type_name(&opts->func_inst.group, "", &hid_func_type); | ||
881 | |||
882 | unlock: | ||
883 | mutex_unlock(&hidg_ida_lock); | ||
884 | return ret; | ||
885 | } | ||
886 | |||
887 | static void hidg_free(struct usb_function *f) | ||
888 | { | ||
889 | struct f_hidg *hidg; | ||
890 | struct f_hid_opts *opts; | ||
891 | |||
892 | hidg = func_to_hidg(f); | ||
893 | opts = container_of(f->fi, struct f_hid_opts, func_inst); | ||
894 | kfree(hidg->report_desc); | ||
895 | kfree(hidg); | ||
896 | mutex_lock(&opts->lock); | ||
897 | --opts->refcnt; | ||
898 | mutex_unlock(&opts->lock); | ||
899 | } | ||
900 | |||
901 | static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) | ||
902 | { | ||
903 | struct f_hidg *hidg = func_to_hidg(f); | ||
904 | |||
905 | device_destroy(hidg_class, MKDEV(major, hidg->minor)); | ||
906 | cdev_del(&hidg->cdev); | ||
907 | |||
908 | /* disable/free request and end point */ | ||
909 | usb_ep_disable(hidg->in_ep); | ||
910 | usb_ep_dequeue(hidg->in_ep, hidg->req); | ||
911 | kfree(hidg->req->buf); | ||
912 | usb_ep_free_request(hidg->in_ep, hidg->req); | ||
913 | |||
914 | usb_free_all_descriptors(f); | ||
915 | } | ||
916 | |||
917 | static struct usb_function *hidg_alloc(struct usb_function_instance *fi) | ||
918 | { | ||
919 | struct f_hidg *hidg; | ||
920 | struct f_hid_opts *opts; | ||
702 | 921 | ||
703 | /* allocate and initialize one new instance */ | 922 | /* allocate and initialize one new instance */ |
704 | hidg = kzalloc(sizeof *hidg, GFP_KERNEL); | 923 | hidg = kzalloc(sizeof(*hidg), GFP_KERNEL); |
705 | if (!hidg) | 924 | if (!hidg) |
706 | return -ENOMEM; | 925 | return ERR_PTR(-ENOMEM); |
707 | 926 | ||
708 | hidg->minor = index; | 927 | opts = container_of(fi, struct f_hid_opts, func_inst); |
709 | hidg->bInterfaceSubClass = fdesc->subclass; | 928 | |
710 | hidg->bInterfaceProtocol = fdesc->protocol; | 929 | mutex_lock(&opts->lock); |
711 | hidg->report_length = fdesc->report_length; | 930 | ++opts->refcnt; |
712 | hidg->report_desc_length = fdesc->report_desc_length; | 931 | |
713 | hidg->report_desc = kmemdup(fdesc->report_desc, | 932 | hidg->minor = opts->minor; |
714 | fdesc->report_desc_length, | 933 | hidg->bInterfaceSubClass = opts->subclass; |
715 | GFP_KERNEL); | 934 | hidg->bInterfaceProtocol = opts->protocol; |
716 | if (!hidg->report_desc) { | 935 | hidg->report_length = opts->report_length; |
717 | kfree(hidg); | 936 | hidg->report_desc_length = opts->report_desc_length; |
718 | return -ENOMEM; | 937 | if (opts->report_desc) { |
938 | hidg->report_desc = kmemdup(opts->report_desc, | ||
939 | opts->report_desc_length, | ||
940 | GFP_KERNEL); | ||
941 | if (!hidg->report_desc) { | ||
942 | kfree(hidg); | ||
943 | mutex_unlock(&opts->lock); | ||
944 | return ERR_PTR(-ENOMEM); | ||
945 | } | ||
719 | } | 946 | } |
720 | 947 | ||
948 | mutex_unlock(&opts->lock); | ||
949 | |||
721 | hidg->func.name = "hid"; | 950 | hidg->func.name = "hid"; |
722 | hidg->func.strings = ct_func_strings; | ||
723 | hidg->func.bind = hidg_bind; | 951 | hidg->func.bind = hidg_bind; |
724 | hidg->func.unbind = hidg_unbind; | 952 | hidg->func.unbind = hidg_unbind; |
725 | hidg->func.set_alt = hidg_set_alt; | 953 | hidg->func.set_alt = hidg_set_alt; |
726 | hidg->func.disable = hidg_disable; | 954 | hidg->func.disable = hidg_disable; |
727 | hidg->func.setup = hidg_setup; | 955 | hidg->func.setup = hidg_setup; |
956 | hidg->func.free_func = hidg_free; | ||
728 | 957 | ||
729 | /* this could me made configurable at some point */ | 958 | /* this could me made configurable at some point */ |
730 | hidg->qlen = 4; | 959 | hidg->qlen = 4; |
731 | 960 | ||
732 | status = usb_add_function(c, &hidg->func); | 961 | return &hidg->func; |
733 | if (status) | ||
734 | kfree(hidg); | ||
735 | |||
736 | return status; | ||
737 | } | 962 | } |
738 | 963 | ||
739 | int __init ghid_setup(struct usb_gadget *g, int count) | 964 | DECLARE_USB_FUNCTION_INIT(hid, hidg_alloc_inst, hidg_alloc); |
965 | MODULE_LICENSE("GPL"); | ||
966 | MODULE_AUTHOR("Fabien Chouteau"); | ||
967 | |||
968 | int ghid_setup(struct usb_gadget *g, int count) | ||
740 | { | 969 | { |
741 | int status; | 970 | int status; |
742 | dev_t dev; | 971 | dev_t dev; |
743 | 972 | ||
744 | hidg_class = class_create(THIS_MODULE, "hidg"); | 973 | hidg_class = class_create(THIS_MODULE, "hidg"); |
974 | if (IS_ERR(hidg_class)) { | ||
975 | status = PTR_ERR(hidg_class); | ||
976 | hidg_class = NULL; | ||
977 | return status; | ||
978 | } | ||
745 | 979 | ||
746 | status = alloc_chrdev_region(&dev, 0, count, "hidg"); | 980 | status = alloc_chrdev_region(&dev, 0, count, "hidg"); |
747 | if (!status) { | 981 | if (status) { |
748 | major = MAJOR(dev); | 982 | class_destroy(hidg_class); |
749 | minors = count; | 983 | hidg_class = NULL; |
984 | return status; | ||
750 | } | 985 | } |
751 | 986 | ||
752 | return status; | 987 | major = MAJOR(dev); |
988 | minors = count; | ||
989 | |||
990 | return 0; | ||
753 | } | 991 | } |
754 | 992 | ||
755 | void ghid_cleanup(void) | 993 | void ghid_cleanup(void) |
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 807b31c0edc3..a90440300735 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c | |||
@@ -20,6 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | ||
23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
24 | #include <linux/device.h> | 25 | #include <linux/device.h> |
25 | 26 | ||
@@ -33,6 +34,7 @@ | |||
33 | #include <linux/usb/midi.h> | 34 | #include <linux/usb/midi.h> |
34 | 35 | ||
35 | #include "u_f.h" | 36 | #include "u_f.h" |
37 | #include "u_midi.h" | ||
36 | 38 | ||
37 | MODULE_AUTHOR("Ben Williamson"); | 39 | MODULE_AUTHOR("Ben Williamson"); |
38 | MODULE_LICENSE("GPL v2"); | 40 | MODULE_LICENSE("GPL v2"); |
@@ -99,7 +101,7 @@ DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); | |||
99 | DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16); | 101 | DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16); |
100 | 102 | ||
101 | /* B.3.1 Standard AC Interface Descriptor */ | 103 | /* B.3.1 Standard AC Interface Descriptor */ |
102 | static struct usb_interface_descriptor ac_interface_desc __initdata = { | 104 | static struct usb_interface_descriptor ac_interface_desc = { |
103 | .bLength = USB_DT_INTERFACE_SIZE, | 105 | .bLength = USB_DT_INTERFACE_SIZE, |
104 | .bDescriptorType = USB_DT_INTERFACE, | 106 | .bDescriptorType = USB_DT_INTERFACE, |
105 | /* .bInterfaceNumber = DYNAMIC */ | 107 | /* .bInterfaceNumber = DYNAMIC */ |
@@ -110,7 +112,7 @@ static struct usb_interface_descriptor ac_interface_desc __initdata = { | |||
110 | }; | 112 | }; |
111 | 113 | ||
112 | /* B.3.2 Class-Specific AC Interface Descriptor */ | 114 | /* B.3.2 Class-Specific AC Interface Descriptor */ |
113 | static struct uac1_ac_header_descriptor_1 ac_header_desc __initdata = { | 115 | static struct uac1_ac_header_descriptor_1 ac_header_desc = { |
114 | .bLength = UAC_DT_AC_HEADER_SIZE(1), | 116 | .bLength = UAC_DT_AC_HEADER_SIZE(1), |
115 | .bDescriptorType = USB_DT_CS_INTERFACE, | 117 | .bDescriptorType = USB_DT_CS_INTERFACE, |
116 | .bDescriptorSubtype = USB_MS_HEADER, | 118 | .bDescriptorSubtype = USB_MS_HEADER, |
@@ -121,7 +123,7 @@ static struct uac1_ac_header_descriptor_1 ac_header_desc __initdata = { | |||
121 | }; | 123 | }; |
122 | 124 | ||
123 | /* B.4.1 Standard MS Interface Descriptor */ | 125 | /* B.4.1 Standard MS Interface Descriptor */ |
124 | static struct usb_interface_descriptor ms_interface_desc __initdata = { | 126 | static struct usb_interface_descriptor ms_interface_desc = { |
125 | .bLength = USB_DT_INTERFACE_SIZE, | 127 | .bLength = USB_DT_INTERFACE_SIZE, |
126 | .bDescriptorType = USB_DT_INTERFACE, | 128 | .bDescriptorType = USB_DT_INTERFACE, |
127 | /* .bInterfaceNumber = DYNAMIC */ | 129 | /* .bInterfaceNumber = DYNAMIC */ |
@@ -132,7 +134,7 @@ static struct usb_interface_descriptor ms_interface_desc __initdata = { | |||
132 | }; | 134 | }; |
133 | 135 | ||
134 | /* B.4.2 Class-Specific MS Interface Descriptor */ | 136 | /* B.4.2 Class-Specific MS Interface Descriptor */ |
135 | static struct usb_ms_header_descriptor ms_header_desc __initdata = { | 137 | static struct usb_ms_header_descriptor ms_header_desc = { |
136 | .bLength = USB_DT_MS_HEADER_SIZE, | 138 | .bLength = USB_DT_MS_HEADER_SIZE, |
137 | .bDescriptorType = USB_DT_CS_INTERFACE, | 139 | .bDescriptorType = USB_DT_CS_INTERFACE, |
138 | .bDescriptorSubtype = USB_MS_HEADER, | 140 | .bDescriptorSubtype = USB_MS_HEADER, |
@@ -387,29 +389,6 @@ static void f_midi_disable(struct usb_function *f) | |||
387 | usb_ep_disable(midi->out_ep); | 389 | usb_ep_disable(midi->out_ep); |
388 | } | 390 | } |
389 | 391 | ||
390 | static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) | ||
391 | { | ||
392 | struct usb_composite_dev *cdev = f->config->cdev; | ||
393 | struct f_midi *midi = func_to_midi(f); | ||
394 | struct snd_card *card; | ||
395 | |||
396 | DBG(cdev, "unbind\n"); | ||
397 | |||
398 | /* just to be sure */ | ||
399 | f_midi_disable(f); | ||
400 | |||
401 | card = midi->card; | ||
402 | midi->card = NULL; | ||
403 | if (card) | ||
404 | snd_card_free(card); | ||
405 | |||
406 | kfree(midi->id); | ||
407 | midi->id = NULL; | ||
408 | |||
409 | usb_free_all_descriptors(f); | ||
410 | kfree(midi); | ||
411 | } | ||
412 | |||
413 | static int f_midi_snd_free(struct snd_device *device) | 392 | static int f_midi_snd_free(struct snd_device *device) |
414 | { | 393 | { |
415 | return 0; | 394 | return 0; |
@@ -654,6 +633,14 @@ static struct snd_rawmidi_ops gmidi_out_ops = { | |||
654 | .trigger = f_midi_out_trigger | 633 | .trigger = f_midi_out_trigger |
655 | }; | 634 | }; |
656 | 635 | ||
636 | static inline void f_midi_unregister_card(struct f_midi *midi) | ||
637 | { | ||
638 | if (midi->card) { | ||
639 | snd_card_free(midi->card); | ||
640 | midi->card = NULL; | ||
641 | } | ||
642 | } | ||
643 | |||
657 | /* register as a sound "card" */ | 644 | /* register as a sound "card" */ |
658 | static int f_midi_register_card(struct f_midi *midi) | 645 | static int f_midi_register_card(struct f_midi *midi) |
659 | { | 646 | { |
@@ -715,17 +702,13 @@ static int f_midi_register_card(struct f_midi *midi) | |||
715 | return 0; | 702 | return 0; |
716 | 703 | ||
717 | fail: | 704 | fail: |
718 | if (midi->card) { | 705 | f_midi_unregister_card(midi); |
719 | snd_card_free(midi->card); | ||
720 | midi->card = NULL; | ||
721 | } | ||
722 | return err; | 706 | return err; |
723 | } | 707 | } |
724 | 708 | ||
725 | /* MIDI function driver setup/binding */ | 709 | /* MIDI function driver setup/binding */ |
726 | 710 | ||
727 | static int __init | 711 | static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) |
728 | f_midi_bind(struct usb_configuration *c, struct usb_function *f) | ||
729 | { | 712 | { |
730 | struct usb_descriptor_header **midi_function; | 713 | struct usb_descriptor_header **midi_function; |
731 | struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS]; | 714 | struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS]; |
@@ -734,15 +717,23 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f) | |||
734 | struct usb_midi_out_jack_descriptor_1 jack_out_emb_desc[MAX_PORTS]; | 717 | struct usb_midi_out_jack_descriptor_1 jack_out_emb_desc[MAX_PORTS]; |
735 | struct usb_composite_dev *cdev = c->cdev; | 718 | struct usb_composite_dev *cdev = c->cdev; |
736 | struct f_midi *midi = func_to_midi(f); | 719 | struct f_midi *midi = func_to_midi(f); |
720 | struct usb_string *us; | ||
737 | int status, n, jack = 1, i = 0; | 721 | int status, n, jack = 1, i = 0; |
738 | 722 | ||
723 | midi->gadget = cdev->gadget; | ||
724 | tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi); | ||
725 | status = f_midi_register_card(midi); | ||
726 | if (status < 0) | ||
727 | goto fail_register; | ||
728 | |||
739 | /* maybe allocate device-global string ID */ | 729 | /* maybe allocate device-global string ID */ |
740 | if (midi_string_defs[0].id == 0) { | 730 | us = usb_gstrings_attach(c->cdev, midi_strings, |
741 | status = usb_string_id(c->cdev); | 731 | ARRAY_SIZE(midi_string_defs)); |
742 | if (status < 0) | 732 | if (IS_ERR(us)) { |
743 | goto fail; | 733 | status = PTR_ERR(us); |
744 | midi_string_defs[0].id = status; | 734 | goto fail; |
745 | } | 735 | } |
736 | ac_interface_desc.iInterface = us[STRING_FUNC_IDX].id; | ||
746 | 737 | ||
747 | /* We have two interfaces, AudioControl and MIDIStreaming */ | 738 | /* We have two interfaces, AudioControl and MIDIStreaming */ |
748 | status = usb_interface_id(c, f); | 739 | status = usb_interface_id(c, f); |
@@ -892,6 +883,8 @@ fail_f_midi: | |||
892 | kfree(midi_function); | 883 | kfree(midi_function); |
893 | usb_free_descriptors(f->hs_descriptors); | 884 | usb_free_descriptors(f->hs_descriptors); |
894 | fail: | 885 | fail: |
886 | f_midi_unregister_card(midi); | ||
887 | fail_register: | ||
895 | /* we might as well release our claims on endpoints */ | 888 | /* we might as well release our claims on endpoints */ |
896 | if (midi->out_ep) | 889 | if (midi->out_ep) |
897 | midi->out_ep->driver_data = NULL; | 890 | midi->out_ep->driver_data = NULL; |
@@ -903,42 +896,235 @@ fail: | |||
903 | return status; | 896 | return status; |
904 | } | 897 | } |
905 | 898 | ||
906 | /** | 899 | static inline struct f_midi_opts *to_f_midi_opts(struct config_item *item) |
907 | * f_midi_bind_config - add USB MIDI function to a configuration | 900 | { |
908 | * @c: the configuration to supcard the USB audio function | 901 | return container_of(to_config_group(item), struct f_midi_opts, |
909 | * @index: the soundcard index to use for the ALSA device creation | 902 | func_inst.group); |
910 | * @id: the soundcard id to use for the ALSA device creation | 903 | } |
911 | * @buflen: the buffer length to use | 904 | |
912 | * @qlen the number of read requests to pre-allocate | 905 | CONFIGFS_ATTR_STRUCT(f_midi_opts); |
913 | * Context: single threaded during gadget setup | 906 | CONFIGFS_ATTR_OPS(f_midi_opts); |
914 | * | 907 | |
915 | * Returns zero on success, else negative errno. | 908 | static void midi_attr_release(struct config_item *item) |
916 | */ | 909 | { |
917 | int __init f_midi_bind_config(struct usb_configuration *c, | 910 | struct f_midi_opts *opts = to_f_midi_opts(item); |
918 | int index, char *id, | 911 | |
919 | unsigned int in_ports, | 912 | usb_put_function_instance(&opts->func_inst); |
920 | unsigned int out_ports, | 913 | } |
921 | unsigned int buflen, | 914 | |
922 | unsigned int qlen) | 915 | static struct configfs_item_operations midi_item_ops = { |
916 | .release = midi_attr_release, | ||
917 | .show_attribute = f_midi_opts_attr_show, | ||
918 | .store_attribute = f_midi_opts_attr_store, | ||
919 | }; | ||
920 | |||
921 | #define F_MIDI_OPT(name, test_limit, limit) \ | ||
922 | static ssize_t f_midi_opts_##name##_show(struct f_midi_opts *opts, char *page) \ | ||
923 | { \ | ||
924 | int result; \ | ||
925 | \ | ||
926 | mutex_lock(&opts->lock); \ | ||
927 | result = sprintf(page, "%d\n", opts->name); \ | ||
928 | mutex_unlock(&opts->lock); \ | ||
929 | \ | ||
930 | return result; \ | ||
931 | } \ | ||
932 | \ | ||
933 | static ssize_t f_midi_opts_##name##_store(struct f_midi_opts *opts, \ | ||
934 | const char *page, size_t len) \ | ||
935 | { \ | ||
936 | int ret; \ | ||
937 | u32 num; \ | ||
938 | \ | ||
939 | mutex_lock(&opts->lock); \ | ||
940 | if (opts->refcnt) { \ | ||
941 | ret = -EBUSY; \ | ||
942 | goto end; \ | ||
943 | } \ | ||
944 | \ | ||
945 | ret = kstrtou32(page, 0, &num); \ | ||
946 | if (ret) \ | ||
947 | goto end; \ | ||
948 | \ | ||
949 | if (test_limit && num > limit) { \ | ||
950 | ret = -EINVAL; \ | ||
951 | goto end; \ | ||
952 | } \ | ||
953 | opts->name = num; \ | ||
954 | ret = len; \ | ||
955 | \ | ||
956 | end: \ | ||
957 | mutex_unlock(&opts->lock); \ | ||
958 | return ret; \ | ||
959 | } \ | ||
960 | \ | ||
961 | static struct f_midi_opts_attribute f_midi_opts_##name = \ | ||
962 | __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, f_midi_opts_##name##_show, \ | ||
963 | f_midi_opts_##name##_store) | ||
964 | |||
965 | F_MIDI_OPT(index, true, SNDRV_CARDS); | ||
966 | F_MIDI_OPT(buflen, false, 0); | ||
967 | F_MIDI_OPT(qlen, false, 0); | ||
968 | F_MIDI_OPT(in_ports, true, MAX_PORTS); | ||
969 | F_MIDI_OPT(out_ports, true, MAX_PORTS); | ||
970 | |||
971 | static ssize_t f_midi_opts_id_show(struct f_midi_opts *opts, char *page) | ||
972 | { | ||
973 | int result; | ||
974 | |||
975 | mutex_lock(&opts->lock); | ||
976 | result = strlcpy(page, opts->id, PAGE_SIZE); | ||
977 | mutex_unlock(&opts->lock); | ||
978 | |||
979 | return result; | ||
980 | } | ||
981 | |||
982 | static ssize_t f_midi_opts_id_store(struct f_midi_opts *opts, | ||
983 | const char *page, size_t len) | ||
984 | { | ||
985 | int ret; | ||
986 | char *c; | ||
987 | |||
988 | mutex_lock(&opts->lock); | ||
989 | if (opts->refcnt) { | ||
990 | ret = -EBUSY; | ||
991 | goto end; | ||
992 | } | ||
993 | |||
994 | c = kstrndup(page, len, GFP_KERNEL); | ||
995 | if (!c) { | ||
996 | ret = -ENOMEM; | ||
997 | goto end; | ||
998 | } | ||
999 | if (opts->id_allocated) | ||
1000 | kfree(opts->id); | ||
1001 | opts->id = c; | ||
1002 | opts->id_allocated = true; | ||
1003 | ret = len; | ||
1004 | end: | ||
1005 | mutex_unlock(&opts->lock); | ||
1006 | return ret; | ||
1007 | } | ||
1008 | |||
1009 | static struct f_midi_opts_attribute f_midi_opts_id = | ||
1010 | __CONFIGFS_ATTR(id, S_IRUGO | S_IWUSR, f_midi_opts_id_show, | ||
1011 | f_midi_opts_id_store); | ||
1012 | |||
1013 | static struct configfs_attribute *midi_attrs[] = { | ||
1014 | &f_midi_opts_index.attr, | ||
1015 | &f_midi_opts_buflen.attr, | ||
1016 | &f_midi_opts_qlen.attr, | ||
1017 | &f_midi_opts_in_ports.attr, | ||
1018 | &f_midi_opts_out_ports.attr, | ||
1019 | &f_midi_opts_id.attr, | ||
1020 | NULL, | ||
1021 | }; | ||
1022 | |||
1023 | static struct config_item_type midi_func_type = { | ||
1024 | .ct_item_ops = &midi_item_ops, | ||
1025 | .ct_attrs = midi_attrs, | ||
1026 | .ct_owner = THIS_MODULE, | ||
1027 | }; | ||
1028 | |||
1029 | static void f_midi_free_inst(struct usb_function_instance *f) | ||
1030 | { | ||
1031 | struct f_midi_opts *opts; | ||
1032 | |||
1033 | opts = container_of(f, struct f_midi_opts, func_inst); | ||
1034 | |||
1035 | if (opts->id_allocated) | ||
1036 | kfree(opts->id); | ||
1037 | |||
1038 | kfree(opts); | ||
1039 | } | ||
1040 | |||
1041 | static struct usb_function_instance *f_midi_alloc_inst(void) | ||
1042 | { | ||
1043 | struct f_midi_opts *opts; | ||
1044 | |||
1045 | opts = kzalloc(sizeof(*opts), GFP_KERNEL); | ||
1046 | if (!opts) | ||
1047 | return ERR_PTR(-ENOMEM); | ||
1048 | |||
1049 | mutex_init(&opts->lock); | ||
1050 | opts->func_inst.free_func_inst = f_midi_free_inst; | ||
1051 | opts->index = SNDRV_DEFAULT_IDX1; | ||
1052 | opts->id = SNDRV_DEFAULT_STR1; | ||
1053 | opts->buflen = 256; | ||
1054 | opts->qlen = 32; | ||
1055 | opts->in_ports = 1; | ||
1056 | opts->out_ports = 1; | ||
1057 | |||
1058 | config_group_init_type_name(&opts->func_inst.group, "", | ||
1059 | &midi_func_type); | ||
1060 | |||
1061 | return &opts->func_inst; | ||
1062 | } | ||
1063 | |||
1064 | static void f_midi_free(struct usb_function *f) | ||
1065 | { | ||
1066 | struct f_midi *midi; | ||
1067 | struct f_midi_opts *opts; | ||
1068 | int i; | ||
1069 | |||
1070 | midi = func_to_midi(f); | ||
1071 | opts = container_of(f->fi, struct f_midi_opts, func_inst); | ||
1072 | kfree(midi->id); | ||
1073 | mutex_lock(&opts->lock); | ||
1074 | for (i = opts->in_ports - 1; i >= 0; --i) | ||
1075 | kfree(midi->in_port[i]); | ||
1076 | kfree(midi); | ||
1077 | --opts->refcnt; | ||
1078 | mutex_unlock(&opts->lock); | ||
1079 | } | ||
1080 | |||
1081 | static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) | ||
1082 | { | ||
1083 | struct usb_composite_dev *cdev = f->config->cdev; | ||
1084 | struct f_midi *midi = func_to_midi(f); | ||
1085 | struct snd_card *card; | ||
1086 | |||
1087 | DBG(cdev, "unbind\n"); | ||
1088 | |||
1089 | /* just to be sure */ | ||
1090 | f_midi_disable(f); | ||
1091 | |||
1092 | card = midi->card; | ||
1093 | midi->card = NULL; | ||
1094 | if (card) | ||
1095 | snd_card_free(card); | ||
1096 | |||
1097 | usb_free_all_descriptors(f); | ||
1098 | } | ||
1099 | |||
1100 | static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) | ||
923 | { | 1101 | { |
924 | struct f_midi *midi; | 1102 | struct f_midi *midi; |
1103 | struct f_midi_opts *opts; | ||
925 | int status, i; | 1104 | int status, i; |
926 | 1105 | ||
1106 | opts = container_of(fi, struct f_midi_opts, func_inst); | ||
1107 | |||
1108 | mutex_lock(&opts->lock); | ||
927 | /* sanity check */ | 1109 | /* sanity check */ |
928 | if (in_ports > MAX_PORTS || out_ports > MAX_PORTS) | 1110 | if (opts->in_ports > MAX_PORTS || opts->out_ports > MAX_PORTS) { |
929 | return -EINVAL; | 1111 | mutex_unlock(&opts->lock); |
1112 | return ERR_PTR(-EINVAL); | ||
1113 | } | ||
930 | 1114 | ||
931 | /* allocate and initialize one new instance */ | 1115 | /* allocate and initialize one new instance */ |
932 | midi = kzalloc(sizeof *midi, GFP_KERNEL); | 1116 | midi = kzalloc(sizeof(*midi), GFP_KERNEL); |
933 | if (!midi) { | 1117 | if (!midi) { |
934 | status = -ENOMEM; | 1118 | mutex_unlock(&opts->lock); |
935 | goto fail; | 1119 | return ERR_PTR(-ENOMEM); |
936 | } | 1120 | } |
937 | 1121 | ||
938 | for (i = 0; i < in_ports; i++) { | 1122 | for (i = 0; i < opts->in_ports; i++) { |
939 | struct gmidi_in_port *port = kzalloc(sizeof(*port), GFP_KERNEL); | 1123 | struct gmidi_in_port *port = kzalloc(sizeof(*port), GFP_KERNEL); |
1124 | |||
940 | if (!port) { | 1125 | if (!port) { |
941 | status = -ENOMEM; | 1126 | status = -ENOMEM; |
1127 | mutex_unlock(&opts->lock); | ||
942 | goto setup_fail; | 1128 | goto setup_fail; |
943 | } | 1129 | } |
944 | 1130 | ||
@@ -948,39 +1134,37 @@ int __init f_midi_bind_config(struct usb_configuration *c, | |||
948 | midi->in_port[i] = port; | 1134 | midi->in_port[i] = port; |
949 | } | 1135 | } |
950 | 1136 | ||
951 | midi->gadget = c->cdev->gadget; | ||
952 | tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi); | ||
953 | |||
954 | /* set up ALSA midi devices */ | 1137 | /* set up ALSA midi devices */ |
955 | midi->in_ports = in_ports; | 1138 | midi->id = kstrdup(opts->id, GFP_KERNEL); |
956 | midi->out_ports = out_ports; | 1139 | if (opts->id && !midi->id) { |
957 | status = f_midi_register_card(midi); | 1140 | status = -ENOMEM; |
958 | if (status < 0) | 1141 | mutex_unlock(&opts->lock); |
959 | goto setup_fail; | 1142 | goto kstrdup_fail; |
960 | 1143 | } | |
961 | midi->func.name = "gmidi function"; | 1144 | midi->in_ports = opts->in_ports; |
962 | midi->func.strings = midi_strings; | 1145 | midi->out_ports = opts->out_ports; |
963 | midi->func.bind = f_midi_bind; | 1146 | midi->index = opts->index; |
964 | midi->func.unbind = f_midi_unbind; | 1147 | midi->buflen = opts->buflen; |
965 | midi->func.set_alt = f_midi_set_alt; | 1148 | midi->qlen = opts->qlen; |
966 | midi->func.disable = f_midi_disable; | 1149 | ++opts->refcnt; |
967 | 1150 | mutex_unlock(&opts->lock); | |
968 | midi->id = kstrdup(id, GFP_KERNEL); | 1151 | |
969 | midi->index = index; | 1152 | midi->func.name = "gmidi function"; |
970 | midi->buflen = buflen; | 1153 | midi->func.bind = f_midi_bind; |
971 | midi->qlen = qlen; | 1154 | midi->func.unbind = f_midi_unbind; |
972 | 1155 | midi->func.set_alt = f_midi_set_alt; | |
973 | status = usb_add_function(c, &midi->func); | 1156 | midi->func.disable = f_midi_disable; |
974 | if (status) | 1157 | midi->func.free_func = f_midi_free; |
975 | goto setup_fail; | 1158 | |
976 | 1159 | return &midi->func; | |
977 | return 0; | 1160 | |
978 | 1161 | kstrdup_fail: | |
1162 | f_midi_unregister_card(midi); | ||
979 | setup_fail: | 1163 | setup_fail: |
980 | for (--i; i >= 0; i--) | 1164 | for (--i; i >= 0; i--) |
981 | kfree(midi->in_port[i]); | 1165 | kfree(midi->in_port[i]); |
982 | kfree(midi); | 1166 | kfree(midi); |
983 | fail: | 1167 | return ERR_PTR(status); |
984 | return status; | ||
985 | } | 1168 | } |
986 | 1169 | ||
1170 | DECLARE_USB_FUNCTION_INIT(midi, f_midi_alloc_inst, f_midi_alloc); | ||
diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 16361b0a8b46..bdcda9f5148e 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c | |||
@@ -1441,6 +1441,9 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) | |||
1441 | 1441 | ||
1442 | status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function, | 1442 | status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function, |
1443 | NULL); | 1443 | NULL); |
1444 | if (status) | ||
1445 | goto fail; | ||
1446 | |||
1444 | /* | 1447 | /* |
1445 | * NOTE: all that is done without knowing or caring about | 1448 | * NOTE: all that is done without knowing or caring about |
1446 | * the network link ... which is unavailable to this code | 1449 | * the network link ... which is unavailable to this code |
diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index f13fc6a58565..829edf878dac 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c | |||
@@ -375,8 +375,7 @@ static struct sk_buff *rndis_add_header(struct gether *port, | |||
375 | struct sk_buff *skb2; | 375 | struct sk_buff *skb2; |
376 | 376 | ||
377 | skb2 = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type)); | 377 | skb2 = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type)); |
378 | if (skb2) | 378 | rndis_add_hdr(skb2); |
379 | rndis_add_hdr(skb2); | ||
380 | 379 | ||
381 | dev_kfree_skb(skb); | 380 | dev_kfree_skb(skb); |
382 | return skb2; | 381 | return skb2; |
diff --git a/drivers/usb/gadget/function/u_hid.h b/drivers/usb/gadget/function/u_hid.h new file mode 100644 index 000000000000..aaa0e368a159 --- /dev/null +++ b/drivers/usb/gadget/function/u_hid.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * u_hid.h | ||
3 | * | ||
4 | * Utility definitions for the hid function | ||
5 | * | ||
6 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. | ||
7 | * http://www.samsung.com | ||
8 | * | ||
9 | * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #ifndef U_HID_H | ||
17 | #define U_HID_H | ||
18 | |||
19 | #include <linux/usb/composite.h> | ||
20 | |||
21 | struct f_hid_opts { | ||
22 | struct usb_function_instance func_inst; | ||
23 | int minor; | ||
24 | unsigned char subclass; | ||
25 | unsigned char protocol; | ||
26 | unsigned short report_length; | ||
27 | unsigned short report_desc_length; | ||
28 | unsigned char *report_desc; | ||
29 | bool report_desc_alloc; | ||
30 | |||
31 | /* | ||
32 | * Protect the data form concurrent access by read/write | ||
33 | * and create symlink/remove symlink. | ||
34 | */ | ||
35 | struct mutex lock; | ||
36 | int refcnt; | ||
37 | }; | ||
38 | |||
39 | int ghid_setup(struct usb_gadget *g, int count); | ||
40 | void ghid_cleanup(void); | ||
41 | |||
42 | #endif /* U_HID_H */ | ||
diff --git a/drivers/usb/gadget/function/u_midi.h b/drivers/usb/gadget/function/u_midi.h new file mode 100644 index 000000000000..22510189758e --- /dev/null +++ b/drivers/usb/gadget/function/u_midi.h | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * u_midi.h | ||
3 | * | ||
4 | * Utility definitions for the midi function | ||
5 | * | ||
6 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. | ||
7 | * http://www.samsung.com | ||
8 | * | ||
9 | * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #ifndef U_MIDI_H | ||
17 | #define U_MIDI_H | ||
18 | |||
19 | #include <linux/usb/composite.h> | ||
20 | |||
21 | struct f_midi_opts { | ||
22 | struct usb_function_instance func_inst; | ||
23 | int index; | ||
24 | char *id; | ||
25 | bool id_allocated; | ||
26 | unsigned int in_ports; | ||
27 | unsigned int out_ports; | ||
28 | unsigned int buflen; | ||
29 | unsigned int qlen; | ||
30 | |||
31 | /* | ||
32 | * Protect the data form concurrent access by read/write | ||
33 | * and create symlink/remove symlink. | ||
34 | */ | ||
35 | struct mutex lock; | ||
36 | int refcnt; | ||
37 | }; | ||
38 | |||
39 | #endif /* U_MIDI_H */ | ||
40 | |||
diff --git a/drivers/usb/gadget/function/u_uac1.c b/drivers/usb/gadget/function/u_uac1.c index a44a07f30281..53842a1b947f 100644 --- a/drivers/usb/gadget/function/u_uac1.c +++ b/drivers/usb/gadget/function/u_uac1.c | |||
@@ -213,9 +213,6 @@ static int gaudio_open_snd_dev(struct gaudio *card) | |||
213 | fn_cap = opts->fn_cap; | 213 | fn_cap = opts->fn_cap; |
214 | fn_cntl = opts->fn_cntl; | 214 | fn_cntl = opts->fn_cntl; |
215 | 215 | ||
216 | if (!card) | ||
217 | return -ENODEV; | ||
218 | |||
219 | /* Open control device */ | 216 | /* Open control device */ |
220 | snd = &card->control; | 217 | snd = &card->control; |
221 | snd->filp = filp_open(fn_cntl, O_RDWR, 0); | 218 | snd->filp = filp_open(fn_cntl, O_RDWR, 0); |
diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index 24392d269709..fd48ef3af4eb 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig | |||
@@ -287,6 +287,7 @@ config USB_MIDI_GADGET | |||
287 | depends on SND | 287 | depends on SND |
288 | select USB_LIBCOMPOSITE | 288 | select USB_LIBCOMPOSITE |
289 | select SND_RAWMIDI | 289 | select SND_RAWMIDI |
290 | select USB_F_MIDI | ||
290 | help | 291 | help |
291 | The MIDI Gadget acts as a USB Audio device, with one MIDI | 292 | The MIDI Gadget acts as a USB Audio device, with one MIDI |
292 | input and one MIDI output. These MIDI jacks appear as | 293 | input and one MIDI output. These MIDI jacks appear as |
@@ -419,6 +420,7 @@ endif # TTY | |||
419 | config USB_G_HID | 420 | config USB_G_HID |
420 | tristate "HID Gadget" | 421 | tristate "HID Gadget" |
421 | select USB_LIBCOMPOSITE | 422 | select USB_LIBCOMPOSITE |
423 | select USB_F_HID | ||
422 | help | 424 | help |
423 | The HID gadget driver provides generic emulation of USB | 425 | The HID gadget driver provides generic emulation of USB |
424 | Human Interface Devices (HID). | 426 | Human Interface Devices (HID). |
diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 1b075132f8f1..633683a72a11 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c | |||
@@ -237,7 +237,7 @@ static void dbgp_unbind(struct usb_gadget *gadget) | |||
237 | static unsigned char tty_line; | 237 | static unsigned char tty_line; |
238 | #endif | 238 | #endif |
239 | 239 | ||
240 | static int __init dbgp_configure_endpoints(struct usb_gadget *gadget) | 240 | static int dbgp_configure_endpoints(struct usb_gadget *gadget) |
241 | { | 241 | { |
242 | int stp; | 242 | int stp; |
243 | 243 | ||
@@ -273,19 +273,10 @@ static int __init dbgp_configure_endpoints(struct usb_gadget *gadget) | |||
273 | 273 | ||
274 | dbgp.serial->in->desc = &i_desc; | 274 | dbgp.serial->in->desc = &i_desc; |
275 | dbgp.serial->out->desc = &o_desc; | 275 | dbgp.serial->out->desc = &o_desc; |
276 | 276 | #endif | |
277 | if (gserial_alloc_line(&tty_line)) { | ||
278 | stp = 3; | ||
279 | goto fail_3; | ||
280 | } | ||
281 | 277 | ||
282 | return 0; | 278 | return 0; |
283 | 279 | ||
284 | fail_3: | ||
285 | dbgp.o_ep->driver_data = NULL; | ||
286 | #else | ||
287 | return 0; | ||
288 | #endif | ||
289 | fail_2: | 280 | fail_2: |
290 | dbgp.i_ep->driver_data = NULL; | 281 | dbgp.i_ep->driver_data = NULL; |
291 | fail_1: | 282 | fail_1: |
@@ -324,10 +315,17 @@ static int __init dbgp_bind(struct usb_gadget *gadget, | |||
324 | err = -ENOMEM; | 315 | err = -ENOMEM; |
325 | goto fail; | 316 | goto fail; |
326 | } | 317 | } |
318 | |||
319 | if (gserial_alloc_line(&tty_line)) { | ||
320 | stp = 4; | ||
321 | err = -ENODEV; | ||
322 | goto fail; | ||
323 | } | ||
327 | #endif | 324 | #endif |
325 | |||
328 | err = dbgp_configure_endpoints(gadget); | 326 | err = dbgp_configure_endpoints(gadget); |
329 | if (err < 0) { | 327 | if (err < 0) { |
330 | stp = 4; | 328 | stp = 5; |
331 | goto fail; | 329 | goto fail; |
332 | } | 330 | } |
333 | 331 | ||
@@ -383,6 +381,10 @@ static int dbgp_setup(struct usb_gadget *gadget, | |||
383 | #ifdef CONFIG_USB_G_DBGP_PRINTK | 381 | #ifdef CONFIG_USB_G_DBGP_PRINTK |
384 | err = dbgp_enable_ep(); | 382 | err = dbgp_enable_ep(); |
385 | #else | 383 | #else |
384 | err = dbgp_configure_endpoints(gadget); | ||
385 | if (err < 0) { | ||
386 | goto fail; | ||
387 | } | ||
386 | err = gserial_connect(dbgp.serial, tty_line); | 388 | err = gserial_connect(dbgp.serial, tty_line); |
387 | #endif | 389 | #endif |
388 | if (err < 0) | 390 | if (err < 0) |
diff --git a/drivers/usb/gadget/legacy/gmidi.c b/drivers/usb/gadget/legacy/gmidi.c index 3d696b86ff76..e02a095294ac 100644 --- a/drivers/usb/gadget/legacy/gmidi.c +++ b/drivers/usb/gadget/legacy/gmidi.c | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | #include "gadget_chips.h" | 38 | #include "gadget_chips.h" |
39 | 39 | ||
40 | #include "f_midi.c" | 40 | #include "u_midi.h" |
41 | 41 | ||
42 | /*-------------------------------------------------------------------------*/ | 42 | /*-------------------------------------------------------------------------*/ |
43 | 43 | ||
@@ -115,8 +115,13 @@ static struct usb_gadget_strings *dev_strings[] = { | |||
115 | NULL, | 115 | NULL, |
116 | }; | 116 | }; |
117 | 117 | ||
118 | static struct usb_function_instance *fi_midi; | ||
119 | static struct usb_function *f_midi; | ||
120 | |||
118 | static int __exit midi_unbind(struct usb_composite_dev *dev) | 121 | static int __exit midi_unbind(struct usb_composite_dev *dev) |
119 | { | 122 | { |
123 | usb_put_function(f_midi); | ||
124 | usb_put_function_instance(fi_midi); | ||
120 | return 0; | 125 | return 0; |
121 | } | 126 | } |
122 | 127 | ||
@@ -130,28 +135,54 @@ static struct usb_configuration midi_config = { | |||
130 | 135 | ||
131 | static int __init midi_bind_config(struct usb_configuration *c) | 136 | static int __init midi_bind_config(struct usb_configuration *c) |
132 | { | 137 | { |
133 | return f_midi_bind_config(c, index, id, | 138 | int status; |
134 | in_ports, out_ports, | 139 | |
135 | buflen, qlen); | 140 | f_midi = usb_get_function(fi_midi); |
141 | if (IS_ERR(f_midi)) | ||
142 | return PTR_ERR(f_midi); | ||
143 | |||
144 | status = usb_add_function(c, f_midi); | ||
145 | if (status < 0) { | ||
146 | usb_put_function(f_midi); | ||
147 | return status; | ||
148 | } | ||
149 | |||
150 | return 0; | ||
136 | } | 151 | } |
137 | 152 | ||
138 | static int __init midi_bind(struct usb_composite_dev *cdev) | 153 | static int __init midi_bind(struct usb_composite_dev *cdev) |
139 | { | 154 | { |
155 | struct f_midi_opts *midi_opts; | ||
140 | int status; | 156 | int status; |
141 | 157 | ||
158 | fi_midi = usb_get_function_instance("midi"); | ||
159 | if (IS_ERR(fi_midi)) | ||
160 | return PTR_ERR(fi_midi); | ||
161 | |||
162 | midi_opts = container_of(fi_midi, struct f_midi_opts, func_inst); | ||
163 | midi_opts->index = index; | ||
164 | midi_opts->id = id; | ||
165 | midi_opts->in_ports = in_ports; | ||
166 | midi_opts->out_ports = out_ports; | ||
167 | midi_opts->buflen = buflen; | ||
168 | midi_opts->qlen = qlen; | ||
169 | |||
142 | status = usb_string_ids_tab(cdev, strings_dev); | 170 | status = usb_string_ids_tab(cdev, strings_dev); |
143 | if (status < 0) | 171 | if (status < 0) |
144 | return status; | 172 | goto put; |
145 | device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; | 173 | device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; |
146 | device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; | 174 | device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; |
147 | midi_config.iConfiguration = strings_dev[STRING_DESCRIPTION_IDX].id; | 175 | midi_config.iConfiguration = strings_dev[STRING_DESCRIPTION_IDX].id; |
148 | 176 | ||
149 | status = usb_add_config(cdev, &midi_config, midi_bind_config); | 177 | status = usb_add_config(cdev, &midi_config, midi_bind_config); |
150 | if (status < 0) | 178 | if (status < 0) |
151 | return status; | 179 | goto put; |
152 | usb_composite_overwrite_options(cdev, &coverwrite); | 180 | usb_composite_overwrite_options(cdev, &coverwrite); |
153 | pr_info("%s\n", longname); | 181 | pr_info("%s\n", longname); |
154 | return 0; | 182 | return 0; |
183 | put: | ||
184 | usb_put_function_instance(fi_midi); | ||
185 | return status; | ||
155 | } | 186 | } |
156 | 187 | ||
157 | static __refdata struct usb_composite_driver midi_driver = { | 188 | static __refdata struct usb_composite_driver midi_driver = { |
diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 778613eb37af..633fe7e07688 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c | |||
@@ -17,11 +17,14 @@ | |||
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/usb/composite.h> | 19 | #include <linux/usb/composite.h> |
20 | #include <linux/usb/g_hid.h> | ||
20 | 21 | ||
21 | #include "gadget_chips.h" | 22 | #include "gadget_chips.h" |
22 | #define DRIVER_DESC "HID Gadget" | 23 | #define DRIVER_DESC "HID Gadget" |
23 | #define DRIVER_VERSION "2010/03/16" | 24 | #define DRIVER_VERSION "2010/03/16" |
24 | 25 | ||
26 | #include "u_hid.h" | ||
27 | |||
25 | /*-------------------------------------------------------------------------*/ | 28 | /*-------------------------------------------------------------------------*/ |
26 | 29 | ||
27 | #define HIDG_VENDOR_NUM 0x0525 /* XXX NetChip */ | 30 | #define HIDG_VENDOR_NUM 0x0525 /* XXX NetChip */ |
@@ -29,17 +32,9 @@ | |||
29 | 32 | ||
30 | /*-------------------------------------------------------------------------*/ | 33 | /*-------------------------------------------------------------------------*/ |
31 | 34 | ||
32 | /* | ||
33 | * kbuild is not very cooperative with respect to linking separately | ||
34 | * compiled library objects into one module. So for now we won't use | ||
35 | * separate compilation ... ensuring init/exit sections work to shrink | ||
36 | * the runtime footprint, and giving us at least some parts of what | ||
37 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
38 | */ | ||
39 | #include "f_hid.c" | ||
40 | |||
41 | |||
42 | struct hidg_func_node { | 35 | struct hidg_func_node { |
36 | struct usb_function_instance *fi; | ||
37 | struct usb_function *f; | ||
43 | struct list_head node; | 38 | struct list_head node; |
44 | struct hidg_func_descriptor *func; | 39 | struct hidg_func_descriptor *func; |
45 | }; | 40 | }; |
@@ -113,8 +108,8 @@ static struct usb_gadget_strings *dev_strings[] = { | |||
113 | 108 | ||
114 | static int __init do_config(struct usb_configuration *c) | 109 | static int __init do_config(struct usb_configuration *c) |
115 | { | 110 | { |
116 | struct hidg_func_node *e; | 111 | struct hidg_func_node *e, *n; |
117 | int func = 0, status = 0; | 112 | int status = 0; |
118 | 113 | ||
119 | if (gadget_is_otg(c->cdev->gadget)) { | 114 | if (gadget_is_otg(c->cdev->gadget)) { |
120 | c->descriptors = otg_desc; | 115 | c->descriptors = otg_desc; |
@@ -122,11 +117,24 @@ static int __init do_config(struct usb_configuration *c) | |||
122 | } | 117 | } |
123 | 118 | ||
124 | list_for_each_entry(e, &hidg_func_list, node) { | 119 | list_for_each_entry(e, &hidg_func_list, node) { |
125 | status = hidg_bind_config(c, e->func, func++); | 120 | e->f = usb_get_function(e->fi); |
126 | if (status) | 121 | if (IS_ERR(e->f)) |
127 | break; | 122 | goto put; |
123 | status = usb_add_function(c, e->f); | ||
124 | if (status < 0) { | ||
125 | usb_put_function(e->f); | ||
126 | goto put; | ||
127 | } | ||
128 | } | 128 | } |
129 | 129 | ||
130 | return 0; | ||
131 | put: | ||
132 | list_for_each_entry(n, &hidg_func_list, node) { | ||
133 | if (n == e) | ||
134 | break; | ||
135 | usb_remove_function(c, n->f); | ||
136 | usb_put_function(n->f); | ||
137 | } | ||
130 | return status; | 138 | return status; |
131 | } | 139 | } |
132 | 140 | ||
@@ -143,6 +151,8 @@ static int __init hid_bind(struct usb_composite_dev *cdev) | |||
143 | { | 151 | { |
144 | struct usb_gadget *gadget = cdev->gadget; | 152 | struct usb_gadget *gadget = cdev->gadget; |
145 | struct list_head *tmp; | 153 | struct list_head *tmp; |
154 | struct hidg_func_node *n, *m; | ||
155 | struct f_hid_opts *hid_opts; | ||
146 | int status, funcs = 0; | 156 | int status, funcs = 0; |
147 | 157 | ||
148 | list_for_each(tmp, &hidg_func_list) | 158 | list_for_each(tmp, &hidg_func_list) |
@@ -151,10 +161,20 @@ static int __init hid_bind(struct usb_composite_dev *cdev) | |||
151 | if (!funcs) | 161 | if (!funcs) |
152 | return -ENODEV; | 162 | return -ENODEV; |
153 | 163 | ||
154 | /* set up HID */ | 164 | list_for_each_entry(n, &hidg_func_list, node) { |
155 | status = ghid_setup(cdev->gadget, funcs); | 165 | n->fi = usb_get_function_instance("hid"); |
156 | if (status < 0) | 166 | if (IS_ERR(n->fi)) { |
157 | return status; | 167 | status = PTR_ERR(n->fi); |
168 | goto put; | ||
169 | } | ||
170 | hid_opts = container_of(n->fi, struct f_hid_opts, func_inst); | ||
171 | hid_opts->subclass = n->func->subclass; | ||
172 | hid_opts->protocol = n->func->protocol; | ||
173 | hid_opts->report_length = n->func->report_length; | ||
174 | hid_opts->report_desc_length = n->func->report_desc_length; | ||
175 | hid_opts->report_desc = n->func->report_desc; | ||
176 | } | ||
177 | |||
158 | 178 | ||
159 | /* Allocate string descriptor numbers ... note that string | 179 | /* Allocate string descriptor numbers ... note that string |
160 | * contents can be overridden by the composite_dev glue. | 180 | * contents can be overridden by the composite_dev glue. |
@@ -162,24 +182,37 @@ static int __init hid_bind(struct usb_composite_dev *cdev) | |||
162 | 182 | ||
163 | status = usb_string_ids_tab(cdev, strings_dev); | 183 | status = usb_string_ids_tab(cdev, strings_dev); |
164 | if (status < 0) | 184 | if (status < 0) |
165 | return status; | 185 | goto put; |
166 | device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; | 186 | device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; |
167 | device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; | 187 | device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; |
168 | 188 | ||
169 | /* register our configuration */ | 189 | /* register our configuration */ |
170 | status = usb_add_config(cdev, &config_driver, do_config); | 190 | status = usb_add_config(cdev, &config_driver, do_config); |
171 | if (status < 0) | 191 | if (status < 0) |
172 | return status; | 192 | goto put; |
173 | 193 | ||
174 | usb_composite_overwrite_options(cdev, &coverwrite); | 194 | usb_composite_overwrite_options(cdev, &coverwrite); |
175 | dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); | 195 | dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); |
176 | 196 | ||
177 | return 0; | 197 | return 0; |
198 | |||
199 | put: | ||
200 | list_for_each_entry(m, &hidg_func_list, node) { | ||
201 | if (m == n) | ||
202 | break; | ||
203 | usb_put_function_instance(m->fi); | ||
204 | } | ||
205 | return status; | ||
178 | } | 206 | } |
179 | 207 | ||
180 | static int __exit hid_unbind(struct usb_composite_dev *cdev) | 208 | static int __exit hid_unbind(struct usb_composite_dev *cdev) |
181 | { | 209 | { |
182 | ghid_cleanup(); | 210 | struct hidg_func_node *n; |
211 | |||
212 | list_for_each_entry(n, &hidg_func_list, node) { | ||
213 | usb_put_function(n->f); | ||
214 | usb_put_function_instance(n->fi); | ||
215 | } | ||
183 | return 0; | 216 | return 0; |
184 | } | 217 | } |
185 | 218 | ||
@@ -260,7 +293,7 @@ module_init(hidg_init); | |||
260 | 293 | ||
261 | static void __exit hidg_cleanup(void) | 294 | static void __exit hidg_cleanup(void) |
262 | { | 295 | { |
263 | platform_driver_unregister(&hidg_plat_driver); | ||
264 | usb_composite_unregister(&hidg_driver); | 296 | usb_composite_unregister(&hidg_driver); |
297 | platform_driver_unregister(&hidg_plat_driver); | ||
265 | } | 298 | } |
266 | module_exit(hidg_cleanup); | 299 | module_exit(hidg_cleanup); |
diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 6474081dcbaf..90545980542f 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c | |||
@@ -208,6 +208,43 @@ static struct usb_descriptor_header *hs_printer_function[] = { | |||
208 | NULL | 208 | NULL |
209 | }; | 209 | }; |
210 | 210 | ||
211 | /* | ||
212 | * Added endpoint descriptors for 3.0 devices | ||
213 | */ | ||
214 | |||
215 | static struct usb_endpoint_descriptor ss_ep_in_desc = { | ||
216 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
217 | .bDescriptorType = USB_DT_ENDPOINT, | ||
218 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
219 | .wMaxPacketSize = cpu_to_le16(1024), | ||
220 | }; | ||
221 | |||
222 | static struct usb_ss_ep_comp_descriptor ss_ep_in_comp_desc = { | ||
223 | .bLength = sizeof(ss_ep_in_comp_desc), | ||
224 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
225 | }; | ||
226 | |||
227 | static struct usb_endpoint_descriptor ss_ep_out_desc = { | ||
228 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
229 | .bDescriptorType = USB_DT_ENDPOINT, | ||
230 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
231 | .wMaxPacketSize = cpu_to_le16(1024), | ||
232 | }; | ||
233 | |||
234 | static struct usb_ss_ep_comp_descriptor ss_ep_out_comp_desc = { | ||
235 | .bLength = sizeof(ss_ep_out_comp_desc), | ||
236 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
237 | }; | ||
238 | |||
239 | static struct usb_descriptor_header *ss_printer_function[] = { | ||
240 | (struct usb_descriptor_header *) &intf_desc, | ||
241 | (struct usb_descriptor_header *) &ss_ep_in_desc, | ||
242 | (struct usb_descriptor_header *) &ss_ep_in_comp_desc, | ||
243 | (struct usb_descriptor_header *) &ss_ep_out_desc, | ||
244 | (struct usb_descriptor_header *) &ss_ep_out_comp_desc, | ||
245 | NULL | ||
246 | }; | ||
247 | |||
211 | static struct usb_otg_descriptor otg_descriptor = { | 248 | static struct usb_otg_descriptor otg_descriptor = { |
212 | .bLength = sizeof otg_descriptor, | 249 | .bLength = sizeof otg_descriptor, |
213 | .bDescriptorType = USB_DT_OTG, | 250 | .bDescriptorType = USB_DT_OTG, |
@@ -220,7 +257,20 @@ static const struct usb_descriptor_header *otg_desc[] = { | |||
220 | }; | 257 | }; |
221 | 258 | ||
222 | /* maxpacket and other transfer characteristics vary by speed. */ | 259 | /* maxpacket and other transfer characteristics vary by speed. */ |
223 | #define ep_desc(g, hs, fs) (((g)->speed == USB_SPEED_HIGH)?(hs):(fs)) | 260 | static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget, |
261 | struct usb_endpoint_descriptor *fs, | ||
262 | struct usb_endpoint_descriptor *hs, | ||
263 | struct usb_endpoint_descriptor *ss) | ||
264 | { | ||
265 | switch (gadget->speed) { | ||
266 | case USB_SPEED_SUPER: | ||
267 | return ss; | ||
268 | case USB_SPEED_HIGH: | ||
269 | return hs; | ||
270 | default: | ||
271 | return fs; | ||
272 | } | ||
273 | } | ||
224 | 274 | ||
225 | /*-------------------------------------------------------------------------*/ | 275 | /*-------------------------------------------------------------------------*/ |
226 | 276 | ||
@@ -793,11 +843,12 @@ set_printer_interface(struct printer_dev *dev) | |||
793 | { | 843 | { |
794 | int result = 0; | 844 | int result = 0; |
795 | 845 | ||
796 | dev->in_ep->desc = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc); | 846 | dev->in_ep->desc = ep_desc(dev->gadget, &fs_ep_in_desc, &hs_ep_in_desc, |
847 | &ss_ep_in_desc); | ||
797 | dev->in_ep->driver_data = dev; | 848 | dev->in_ep->driver_data = dev; |
798 | 849 | ||
799 | dev->out_ep->desc = ep_desc(dev->gadget, &hs_ep_out_desc, | 850 | dev->out_ep->desc = ep_desc(dev->gadget, &fs_ep_out_desc, |
800 | &fs_ep_out_desc); | 851 | &hs_ep_out_desc, &ss_ep_out_desc); |
801 | dev->out_ep->driver_data = dev; | 852 | dev->out_ep->driver_data = dev; |
802 | 853 | ||
803 | result = usb_ep_enable(dev->in_ep); | 854 | result = usb_ep_enable(dev->in_ep); |
@@ -1016,9 +1067,11 @@ autoconf_fail: | |||
1016 | /* assumes that all endpoints are dual-speed */ | 1067 | /* assumes that all endpoints are dual-speed */ |
1017 | hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; | 1068 | hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; |
1018 | hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; | 1069 | hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; |
1070 | ss_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; | ||
1071 | ss_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; | ||
1019 | 1072 | ||
1020 | ret = usb_assign_descriptors(f, fs_printer_function, | 1073 | ret = usb_assign_descriptors(f, fs_printer_function, |
1021 | hs_printer_function, NULL); | 1074 | hs_printer_function, ss_printer_function); |
1022 | if (ret) | 1075 | if (ret) |
1023 | return ret; | 1076 | return ret; |
1024 | 1077 | ||
@@ -1253,7 +1306,7 @@ static __refdata struct usb_composite_driver printer_driver = { | |||
1253 | .name = shortname, | 1306 | .name = shortname, |
1254 | .dev = &device_desc, | 1307 | .dev = &device_desc, |
1255 | .strings = dev_strings, | 1308 | .strings = dev_strings, |
1256 | .max_speed = USB_SPEED_HIGH, | 1309 | .max_speed = USB_SPEED_SUPER, |
1257 | .bind = printer_bind, | 1310 | .bind = printer_bind, |
1258 | .unbind = printer_unbind, | 1311 | .unbind = printer_unbind, |
1259 | }; | 1312 | }; |
diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 217365d35a25..b8e213eb36cc 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig | |||
@@ -241,6 +241,8 @@ config USB_M66592 | |||
241 | dynamically linked module called "m66592_udc" and force all | 241 | dynamically linked module called "m66592_udc" and force all |
242 | gadget drivers to also be dynamically linked. | 242 | gadget drivers to also be dynamically linked. |
243 | 243 | ||
244 | source "drivers/usb/gadget/udc/bdc/Kconfig" | ||
245 | |||
244 | # | 246 | # |
245 | # Controllers available only in discrete form (and all PCI controllers) | 247 | # Controllers available only in discrete form (and all PCI controllers) |
246 | # | 248 | # |
diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile index a7f4491593f1..fba2049bf985 100644 --- a/drivers/usb/gadget/udc/Makefile +++ b/drivers/usb/gadget/udc/Makefile | |||
@@ -30,3 +30,4 @@ obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o | |||
30 | obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o | 30 | obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o |
31 | obj-$(CONFIG_USB_GR_UDC) += gr_udc.o | 31 | obj-$(CONFIG_USB_GR_UDC) += gr_udc.o |
32 | obj-$(CONFIG_USB_GADGET_XILINX) += udc-xilinx.o | 32 | obj-$(CONFIG_USB_GADGET_XILINX) += udc-xilinx.o |
33 | obj-$(CONFIG_USB_BDC_UDC) += bdc/ | ||
diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 3b9d13848a4f..de7e5e2ccf1c 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c | |||
@@ -1401,9 +1401,8 @@ static int udc_wakeup(struct usb_gadget *gadget) | |||
1401 | 1401 | ||
1402 | static int amd5536_udc_start(struct usb_gadget *g, | 1402 | static int amd5536_udc_start(struct usb_gadget *g, |
1403 | struct usb_gadget_driver *driver); | 1403 | struct usb_gadget_driver *driver); |
1404 | static int amd5536_udc_stop(struct usb_gadget *g, | 1404 | static int amd5536_udc_stop(struct usb_gadget *g); |
1405 | struct usb_gadget_driver *driver); | 1405 | |
1406 | /* gadget operations */ | ||
1407 | static const struct usb_gadget_ops udc_ops = { | 1406 | static const struct usb_gadget_ops udc_ops = { |
1408 | .wakeup = udc_wakeup, | 1407 | .wakeup = udc_wakeup, |
1409 | .get_frame = udc_get_frame, | 1408 | .get_frame = udc_get_frame, |
@@ -1962,8 +1961,7 @@ __acquires(dev->lock) | |||
1962 | } | 1961 | } |
1963 | 1962 | ||
1964 | /* Called by gadget driver to unregister itself */ | 1963 | /* Called by gadget driver to unregister itself */ |
1965 | static int amd5536_udc_stop(struct usb_gadget *g, | 1964 | static int amd5536_udc_stop(struct usb_gadget *g) |
1966 | struct usb_gadget_driver *driver) | ||
1967 | { | 1965 | { |
1968 | struct udc *dev = to_amd5536_udc(g); | 1966 | struct udc *dev = to_amd5536_udc(g); |
1969 | unsigned long flags; | 1967 | unsigned long flags; |
@@ -1971,7 +1969,7 @@ static int amd5536_udc_stop(struct usb_gadget *g, | |||
1971 | 1969 | ||
1972 | spin_lock_irqsave(&dev->lock, flags); | 1970 | spin_lock_irqsave(&dev->lock, flags); |
1973 | udc_mask_unused_interrupts(dev); | 1971 | udc_mask_unused_interrupts(dev); |
1974 | shutdown(dev, driver); | 1972 | shutdown(dev, NULL); |
1975 | spin_unlock_irqrestore(&dev->lock, flags); | 1973 | spin_unlock_irqrestore(&dev->lock, flags); |
1976 | 1974 | ||
1977 | dev->driver = NULL; | 1975 | dev->driver = NULL; |
@@ -2873,7 +2871,7 @@ __acquires(dev->lock) | |||
2873 | dev->driver->resume(&dev->gadget); | 2871 | dev->driver->resume(&dev->gadget); |
2874 | dev->sys_suspended = 0; | 2872 | dev->sys_suspended = 0; |
2875 | } | 2873 | } |
2876 | dev->driver->disconnect(&dev->gadget); | 2874 | usb_gadget_udc_reset(&dev->gadget, dev->driver); |
2877 | spin_lock(&dev->lock); | 2875 | spin_lock(&dev->lock); |
2878 | 2876 | ||
2879 | /* disable ep0 to empty req queue */ | 2877 | /* disable ep0 to empty req queue */ |
diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 9968f5331fe4..eb2999c5d03c 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c | |||
@@ -840,6 +840,31 @@ static void udc_reinit(struct at91_udc *udc) | |||
840 | } | 840 | } |
841 | } | 841 | } |
842 | 842 | ||
843 | static void reset_gadget(struct at91_udc *udc) | ||
844 | { | ||
845 | struct usb_gadget_driver *driver = udc->driver; | ||
846 | int i; | ||
847 | |||
848 | if (udc->gadget.speed == USB_SPEED_UNKNOWN) | ||
849 | driver = NULL; | ||
850 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
851 | udc->suspended = 0; | ||
852 | |||
853 | for (i = 0; i < NUM_ENDPOINTS; i++) { | ||
854 | struct at91_ep *ep = &udc->ep[i]; | ||
855 | |||
856 | ep->stopped = 1; | ||
857 | nuke(ep, -ESHUTDOWN); | ||
858 | } | ||
859 | if (driver) { | ||
860 | spin_unlock(&udc->lock); | ||
861 | usb_gadget_udc_reset(&udc->gadget, driver); | ||
862 | spin_lock(&udc->lock); | ||
863 | } | ||
864 | |||
865 | udc_reinit(udc); | ||
866 | } | ||
867 | |||
843 | static void stop_activity(struct at91_udc *udc) | 868 | static void stop_activity(struct at91_udc *udc) |
844 | { | 869 | { |
845 | struct usb_gadget_driver *driver = udc->driver; | 870 | struct usb_gadget_driver *driver = udc->driver; |
@@ -870,12 +895,10 @@ static void clk_on(struct at91_udc *udc) | |||
870 | return; | 895 | return; |
871 | udc->clocked = 1; | 896 | udc->clocked = 1; |
872 | 897 | ||
873 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { | 898 | if (IS_ENABLED(CONFIG_COMMON_CLK)) |
874 | clk_set_rate(udc->uclk, 48000000); | 899 | clk_enable(udc->uclk); |
875 | clk_prepare_enable(udc->uclk); | 900 | clk_enable(udc->iclk); |
876 | } | 901 | clk_enable(udc->fclk); |
877 | clk_prepare_enable(udc->iclk); | ||
878 | clk_prepare_enable(udc->fclk); | ||
879 | } | 902 | } |
880 | 903 | ||
881 | static void clk_off(struct at91_udc *udc) | 904 | static void clk_off(struct at91_udc *udc) |
@@ -884,10 +907,10 @@ static void clk_off(struct at91_udc *udc) | |||
884 | return; | 907 | return; |
885 | udc->clocked = 0; | 908 | udc->clocked = 0; |
886 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 909 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
887 | clk_disable_unprepare(udc->fclk); | 910 | clk_disable(udc->fclk); |
888 | clk_disable_unprepare(udc->iclk); | 911 | clk_disable(udc->iclk); |
889 | if (IS_ENABLED(CONFIG_COMMON_CLK)) | 912 | if (IS_ENABLED(CONFIG_COMMON_CLK)) |
890 | clk_disable_unprepare(udc->uclk); | 913 | clk_disable(udc->uclk); |
891 | } | 914 | } |
892 | 915 | ||
893 | /* | 916 | /* |
@@ -984,8 +1007,8 @@ static int at91_set_selfpowered(struct usb_gadget *gadget, int is_on) | |||
984 | 1007 | ||
985 | static int at91_start(struct usb_gadget *gadget, | 1008 | static int at91_start(struct usb_gadget *gadget, |
986 | struct usb_gadget_driver *driver); | 1009 | struct usb_gadget_driver *driver); |
987 | static int at91_stop(struct usb_gadget *gadget, | 1010 | static int at91_stop(struct usb_gadget *gadget); |
988 | struct usb_gadget_driver *driver); | 1011 | |
989 | static const struct usb_gadget_ops at91_udc_ops = { | 1012 | static const struct usb_gadget_ops at91_udc_ops = { |
990 | .get_frame = at91_get_frame, | 1013 | .get_frame = at91_get_frame, |
991 | .wakeup = at91_wakeup, | 1014 | .wakeup = at91_wakeup, |
@@ -1426,7 +1449,7 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) | |||
1426 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES); | 1449 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES); |
1427 | VDBG("end bus reset\n"); | 1450 | VDBG("end bus reset\n"); |
1428 | udc->addr = 0; | 1451 | udc->addr = 0; |
1429 | stop_activity(udc); | 1452 | reset_gadget(udc); |
1430 | 1453 | ||
1431 | /* enable ep0 */ | 1454 | /* enable ep0 */ |
1432 | at91_udp_write(udc, AT91_UDP_CSR(0), | 1455 | at91_udp_write(udc, AT91_UDP_CSR(0), |
@@ -1512,20 +1535,11 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) | |||
1512 | 1535 | ||
1513 | /*-------------------------------------------------------------------------*/ | 1536 | /*-------------------------------------------------------------------------*/ |
1514 | 1537 | ||
1515 | static void nop_release(struct device *dev) | ||
1516 | { | ||
1517 | /* nothing to free */ | ||
1518 | } | ||
1519 | |||
1520 | static struct at91_udc controller = { | 1538 | static struct at91_udc controller = { |
1521 | .gadget = { | 1539 | .gadget = { |
1522 | .ops = &at91_udc_ops, | 1540 | .ops = &at91_udc_ops, |
1523 | .ep0 = &controller.ep[0].ep, | 1541 | .ep0 = &controller.ep[0].ep, |
1524 | .name = driver_name, | 1542 | .name = driver_name, |
1525 | .dev = { | ||
1526 | .init_name = "gadget", | ||
1527 | .release = nop_release, | ||
1528 | } | ||
1529 | }, | 1543 | }, |
1530 | .ep[0] = { | 1544 | .ep[0] = { |
1531 | .ep = { | 1545 | .ep = { |
@@ -1641,12 +1655,10 @@ static int at91_start(struct usb_gadget *gadget, | |||
1641 | udc->enabled = 1; | 1655 | udc->enabled = 1; |
1642 | udc->selfpowered = 1; | 1656 | udc->selfpowered = 1; |
1643 | 1657 | ||
1644 | DBG("bound to %s\n", driver->driver.name); | ||
1645 | return 0; | 1658 | return 0; |
1646 | } | 1659 | } |
1647 | 1660 | ||
1648 | static int at91_stop(struct usb_gadget *gadget, | 1661 | static int at91_stop(struct usb_gadget *gadget) |
1649 | struct usb_gadget_driver *driver) | ||
1650 | { | 1662 | { |
1651 | struct at91_udc *udc; | 1663 | struct at91_udc *udc; |
1652 | unsigned long flags; | 1664 | unsigned long flags; |
@@ -1659,7 +1671,6 @@ static int at91_stop(struct usb_gadget *gadget, | |||
1659 | 1671 | ||
1660 | udc->driver = NULL; | 1672 | udc->driver = NULL; |
1661 | 1673 | ||
1662 | DBG("unbound from %s\n", driver->driver.name); | ||
1663 | return 0; | 1674 | return 0; |
1664 | } | 1675 | } |
1665 | 1676 | ||
@@ -1780,14 +1791,24 @@ static int at91udc_probe(struct platform_device *pdev) | |||
1780 | } | 1791 | } |
1781 | 1792 | ||
1782 | /* don't do anything until we have both gadget driver and VBUS */ | 1793 | /* don't do anything until we have both gadget driver and VBUS */ |
1794 | if (IS_ENABLED(CONFIG_COMMON_CLK)) { | ||
1795 | clk_set_rate(udc->uclk, 48000000); | ||
1796 | retval = clk_prepare(udc->uclk); | ||
1797 | if (retval) | ||
1798 | goto fail1; | ||
1799 | } | ||
1800 | retval = clk_prepare(udc->fclk); | ||
1801 | if (retval) | ||
1802 | goto fail1a; | ||
1803 | |||
1783 | retval = clk_prepare_enable(udc->iclk); | 1804 | retval = clk_prepare_enable(udc->iclk); |
1784 | if (retval) | 1805 | if (retval) |
1785 | goto fail1; | 1806 | goto fail1b; |
1786 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 1807 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
1787 | at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff); | 1808 | at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff); |
1788 | /* Clear all pending interrupts - UDP may be used by bootloader. */ | 1809 | /* Clear all pending interrupts - UDP may be used by bootloader. */ |
1789 | at91_udp_write(udc, AT91_UDP_ICR, 0xffffffff); | 1810 | at91_udp_write(udc, AT91_UDP_ICR, 0xffffffff); |
1790 | clk_disable_unprepare(udc->iclk); | 1811 | clk_disable(udc->iclk); |
1791 | 1812 | ||
1792 | /* request UDC and maybe VBUS irqs */ | 1813 | /* request UDC and maybe VBUS irqs */ |
1793 | udc->udp_irq = platform_get_irq(pdev, 0); | 1814 | udc->udp_irq = platform_get_irq(pdev, 0); |
@@ -1795,7 +1816,7 @@ static int at91udc_probe(struct platform_device *pdev) | |||
1795 | 0, driver_name, udc); | 1816 | 0, driver_name, udc); |
1796 | if (retval < 0) { | 1817 | if (retval < 0) { |
1797 | DBG("request irq %d failed\n", udc->udp_irq); | 1818 | DBG("request irq %d failed\n", udc->udp_irq); |
1798 | goto fail1; | 1819 | goto fail1c; |
1799 | } | 1820 | } |
1800 | if (gpio_is_valid(udc->board.vbus_pin)) { | 1821 | if (gpio_is_valid(udc->board.vbus_pin)) { |
1801 | retval = gpio_request(udc->board.vbus_pin, "udc_vbus"); | 1822 | retval = gpio_request(udc->board.vbus_pin, "udc_vbus"); |
@@ -1848,6 +1869,13 @@ fail3: | |||
1848 | gpio_free(udc->board.vbus_pin); | 1869 | gpio_free(udc->board.vbus_pin); |
1849 | fail2: | 1870 | fail2: |
1850 | free_irq(udc->udp_irq, udc); | 1871 | free_irq(udc->udp_irq, udc); |
1872 | fail1c: | ||
1873 | clk_unprepare(udc->iclk); | ||
1874 | fail1b: | ||
1875 | clk_unprepare(udc->fclk); | ||
1876 | fail1a: | ||
1877 | if (IS_ENABLED(CONFIG_COMMON_CLK)) | ||
1878 | clk_unprepare(udc->uclk); | ||
1851 | fail1: | 1879 | fail1: |
1852 | if (IS_ENABLED(CONFIG_COMMON_CLK) && !IS_ERR(udc->uclk)) | 1880 | if (IS_ENABLED(CONFIG_COMMON_CLK) && !IS_ERR(udc->uclk)) |
1853 | clk_put(udc->uclk); | 1881 | clk_put(udc->uclk); |
@@ -1896,6 +1924,11 @@ static int __exit at91udc_remove(struct platform_device *pdev) | |||
1896 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1924 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1897 | release_mem_region(res->start, resource_size(res)); | 1925 | release_mem_region(res->start, resource_size(res)); |
1898 | 1926 | ||
1927 | if (IS_ENABLED(CONFIG_COMMON_CLK)) | ||
1928 | clk_unprepare(udc->uclk); | ||
1929 | clk_unprepare(udc->fclk); | ||
1930 | clk_unprepare(udc->iclk); | ||
1931 | |||
1899 | clk_put(udc->iclk); | 1932 | clk_put(udc->iclk); |
1900 | clk_put(udc->fclk); | 1933 | clk_put(udc->fclk); |
1901 | if (IS_ENABLED(CONFIG_COMMON_CLK)) | 1934 | if (IS_ENABLED(CONFIG_COMMON_CLK)) |
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 1529926e20a0..b31747979c4a 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c | |||
@@ -987,8 +987,8 @@ usba_udc_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered) | |||
987 | 987 | ||
988 | static int atmel_usba_start(struct usb_gadget *gadget, | 988 | static int atmel_usba_start(struct usb_gadget *gadget, |
989 | struct usb_gadget_driver *driver); | 989 | struct usb_gadget_driver *driver); |
990 | static int atmel_usba_stop(struct usb_gadget *gadget, | 990 | static int atmel_usba_stop(struct usb_gadget *gadget); |
991 | struct usb_gadget_driver *driver); | 991 | |
992 | static const struct usb_gadget_ops usba_udc_ops = { | 992 | static const struct usb_gadget_ops usba_udc_ops = { |
993 | .get_frame = usba_udc_get_frame, | 993 | .get_frame = usba_udc_get_frame, |
994 | .wakeup = usba_udc_wakeup, | 994 | .wakeup = usba_udc_wakeup, |
@@ -1007,19 +1007,10 @@ static struct usb_endpoint_descriptor usba_ep0_desc = { | |||
1007 | .bInterval = 1, | 1007 | .bInterval = 1, |
1008 | }; | 1008 | }; |
1009 | 1009 | ||
1010 | static void nop_release(struct device *dev) | ||
1011 | { | ||
1012 | |||
1013 | } | ||
1014 | |||
1015 | static struct usb_gadget usba_gadget_template = { | 1010 | static struct usb_gadget usba_gadget_template = { |
1016 | .ops = &usba_udc_ops, | 1011 | .ops = &usba_udc_ops, |
1017 | .max_speed = USB_SPEED_HIGH, | 1012 | .max_speed = USB_SPEED_HIGH, |
1018 | .name = "atmel_usba_udc", | 1013 | .name = "atmel_usba_udc", |
1019 | .dev = { | ||
1020 | .init_name = "gadget", | ||
1021 | .release = nop_release, | ||
1022 | }, | ||
1023 | }; | 1014 | }; |
1024 | 1015 | ||
1025 | /* | 1016 | /* |
@@ -1685,11 +1676,10 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
1685 | usba_writel(udc, INT_CLR, USBA_END_OF_RESET); | 1676 | usba_writel(udc, INT_CLR, USBA_END_OF_RESET); |
1686 | reset_all_endpoints(udc); | 1677 | reset_all_endpoints(udc); |
1687 | 1678 | ||
1688 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | 1679 | if (udc->gadget.speed != USB_SPEED_UNKNOWN && udc->driver) { |
1689 | && udc->driver && udc->driver->disconnect) { | ||
1690 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1680 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1691 | spin_unlock(&udc->lock); | 1681 | spin_unlock(&udc->lock); |
1692 | udc->driver->disconnect(&udc->gadget); | 1682 | usb_gadget_udc_reset(&udc->gadget, udc->driver); |
1693 | spin_lock(&udc->lock); | 1683 | spin_lock(&udc->lock); |
1694 | } | 1684 | } |
1695 | 1685 | ||
@@ -1791,8 +1781,6 @@ static int atmel_usba_start(struct usb_gadget *gadget, | |||
1791 | return ret; | 1781 | return ret; |
1792 | } | 1782 | } |
1793 | 1783 | ||
1794 | DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name); | ||
1795 | |||
1796 | udc->vbus_prev = 0; | 1784 | udc->vbus_prev = 0; |
1797 | if (gpio_is_valid(udc->vbus_pin)) | 1785 | if (gpio_is_valid(udc->vbus_pin)) |
1798 | enable_irq(gpio_to_irq(udc->vbus_pin)); | 1786 | enable_irq(gpio_to_irq(udc->vbus_pin)); |
@@ -1809,8 +1797,7 @@ static int atmel_usba_start(struct usb_gadget *gadget, | |||
1809 | return 0; | 1797 | return 0; |
1810 | } | 1798 | } |
1811 | 1799 | ||
1812 | static int atmel_usba_stop(struct usb_gadget *gadget, | 1800 | static int atmel_usba_stop(struct usb_gadget *gadget) |
1813 | struct usb_gadget_driver *driver) | ||
1814 | { | 1801 | { |
1815 | struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget); | 1802 | struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget); |
1816 | unsigned long flags; | 1803 | unsigned long flags; |
@@ -1830,8 +1817,6 @@ static int atmel_usba_stop(struct usb_gadget *gadget, | |||
1830 | clk_disable_unprepare(udc->hclk); | 1817 | clk_disable_unprepare(udc->hclk); |
1831 | clk_disable_unprepare(udc->pclk); | 1818 | clk_disable_unprepare(udc->pclk); |
1832 | 1819 | ||
1833 | DBG(DBG_GADGET, "unregistered driver `%s'\n", udc->driver->driver.name); | ||
1834 | |||
1835 | udc->driver = NULL; | 1820 | udc->driver = NULL; |
1836 | 1821 | ||
1837 | return 0; | 1822 | return 0; |
diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index 2235b8808700..c790918b337b 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c | |||
@@ -1836,8 +1836,7 @@ static int bcm63xx_udc_start(struct usb_gadget *gadget, | |||
1836 | * @gadget: USB slave device. | 1836 | * @gadget: USB slave device. |
1837 | * @driver: Driver for USB slave devices. | 1837 | * @driver: Driver for USB slave devices. |
1838 | */ | 1838 | */ |
1839 | static int bcm63xx_udc_stop(struct usb_gadget *gadget, | 1839 | static int bcm63xx_udc_stop(struct usb_gadget *gadget) |
1840 | struct usb_gadget_driver *driver) | ||
1841 | { | 1840 | { |
1842 | struct bcm63xx_udc *udc = gadget_to_udc(gadget); | 1841 | struct bcm63xx_udc *udc = gadget_to_udc(gadget); |
1843 | unsigned long flags; | 1842 | unsigned long flags; |
@@ -1963,7 +1962,7 @@ static irqreturn_t bcm63xx_udc_ctrl_isr(int irq, void *dev_id) | |||
1963 | { | 1962 | { |
1964 | struct bcm63xx_udc *udc = dev_id; | 1963 | struct bcm63xx_udc *udc = dev_id; |
1965 | u32 stat; | 1964 | u32 stat; |
1966 | bool disconnected = false; | 1965 | bool disconnected = false, bus_reset = false; |
1967 | 1966 | ||
1968 | stat = usbd_readl(udc, USBD_EVENT_IRQ_STATUS_REG) & | 1967 | stat = usbd_readl(udc, USBD_EVENT_IRQ_STATUS_REG) & |
1969 | usbd_readl(udc, USBD_EVENT_IRQ_MASK_REG); | 1968 | usbd_readl(udc, USBD_EVENT_IRQ_MASK_REG); |
@@ -1991,7 +1990,7 @@ static irqreturn_t bcm63xx_udc_ctrl_isr(int irq, void *dev_id) | |||
1991 | 1990 | ||
1992 | udc->ep0_req_reset = 1; | 1991 | udc->ep0_req_reset = 1; |
1993 | schedule_work(&udc->ep0_wq); | 1992 | schedule_work(&udc->ep0_wq); |
1994 | disconnected = true; | 1993 | bus_reset = true; |
1995 | } | 1994 | } |
1996 | if (stat & BIT(USBD_EVENT_IRQ_SETUP)) { | 1995 | if (stat & BIT(USBD_EVENT_IRQ_SETUP)) { |
1997 | if (bcm63xx_update_link_speed(udc)) { | 1996 | if (bcm63xx_update_link_speed(udc)) { |
@@ -2014,6 +2013,8 @@ static irqreturn_t bcm63xx_udc_ctrl_isr(int irq, void *dev_id) | |||
2014 | 2013 | ||
2015 | if (disconnected && udc->driver) | 2014 | if (disconnected && udc->driver) |
2016 | udc->driver->disconnect(&udc->gadget); | 2015 | udc->driver->disconnect(&udc->gadget); |
2016 | else if (bus_reset && udc->driver) | ||
2017 | usb_gadget_udc_reset(&udc->gadget, udc->driver); | ||
2017 | 2018 | ||
2018 | return IRQ_HANDLED; | 2019 | return IRQ_HANDLED; |
2019 | } | 2020 | } |
@@ -2324,10 +2325,8 @@ static int bcm63xx_udc_probe(struct platform_device *pdev) | |||
2324 | int rc = -ENOMEM, i, irq; | 2325 | int rc = -ENOMEM, i, irq; |
2325 | 2326 | ||
2326 | udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL); | 2327 | udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL); |
2327 | if (!udc) { | 2328 | if (!udc) |
2328 | dev_err(dev, "cannot allocate memory\n"); | ||
2329 | return -ENOMEM; | 2329 | return -ENOMEM; |
2330 | } | ||
2331 | 2330 | ||
2332 | platform_set_drvdata(pdev, udc); | 2331 | platform_set_drvdata(pdev, udc); |
2333 | udc->dev = dev; | 2332 | udc->dev = dev; |
diff --git a/drivers/usb/gadget/udc/bdc/Kconfig b/drivers/usb/gadget/udc/bdc/Kconfig new file mode 100644 index 000000000000..0d7b8c9f72fd --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/Kconfig | |||
@@ -0,0 +1,21 @@ | |||
1 | config USB_BDC_UDC | ||
2 | tristate "Broadcom USB3.0 device controller IP driver(BDC)" | ||
3 | depends on USB_GADGET && HAS_DMA | ||
4 | |||
5 | help | ||
6 | BDC is Broadcom's USB3.0 device controller IP. If your SOC has a BDC IP | ||
7 | then select this driver. | ||
8 | |||
9 | Say "y" here to link the driver statically, or "m" to build a dynamically | ||
10 | linked module called "bdc". | ||
11 | |||
12 | if USB_BDC_UDC | ||
13 | |||
14 | comment "Platform Support" | ||
15 | config USB_BDC_PCI | ||
16 | tristate "BDC support for PCIe based platforms" | ||
17 | depends on PCI | ||
18 | default USB_BDC_UDC | ||
19 | help | ||
20 | Enable support for platforms which have BDC connected through PCIe, such as Lego3 FPGA platform. | ||
21 | endif | ||
diff --git a/drivers/usb/gadget/udc/bdc/Makefile b/drivers/usb/gadget/udc/bdc/Makefile new file mode 100644 index 000000000000..5cf6a3bcdf0f --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | obj-$(CONFIG_USB_BDC_UDC) += bdc.o | ||
2 | bdc-y := bdc_core.o bdc_cmd.o bdc_ep.o bdc_udc.o | ||
3 | |||
4 | ifneq ($(CONFIG_USB_GADGET_VERBOSE),) | ||
5 | bdc-y += bdc_dbg.o | ||
6 | endif | ||
7 | |||
8 | obj-$(CONFIG_USB_BDC_PCI) += bdc_pci.o | ||
diff --git a/drivers/usb/gadget/udc/bdc/bdc.h b/drivers/usb/gadget/udc/bdc/bdc.h new file mode 100644 index 000000000000..dc18a20bf040 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc.h | |||
@@ -0,0 +1,490 @@ | |||
1 | /* | ||
2 | * bdc.h - header for the BRCM BDC USB3.0 device controller | ||
3 | * | ||
4 | * Copyright (C) 2014 Broadcom Corporation | ||
5 | * | ||
6 | * Author: Ashwini Pahuja | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #ifndef __LINUX_BDC_H__ | ||
16 | #define __LINUX_BDC_H__ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/usb.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/list.h> | ||
23 | #include <linux/dma-mapping.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/debugfs.h> | ||
26 | #include <linux/usb/ch9.h> | ||
27 | #include <linux/usb/gadget.h> | ||
28 | #include <asm/unaligned.h> | ||
29 | |||
30 | #define BRCM_BDC_NAME "bdc_usb3" | ||
31 | #define BRCM_BDC_DESC "BDC device controller driver" | ||
32 | |||
33 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
34 | |||
35 | /* BDC command operation timeout in usec*/ | ||
36 | #define BDC_CMD_TIMEOUT 1000 | ||
37 | /* BDC controller operation timeout in usec*/ | ||
38 | #define BDC_COP_TIMEOUT 500 | ||
39 | |||
40 | /* | ||
41 | * Maximum size of ep0 response buffer for ch9 requests, | ||
42 | * the set_sel request uses 6 so far, the max. | ||
43 | */ | ||
44 | #define EP0_RESPONSE_BUFF 6 | ||
45 | /* Start with SS as default */ | ||
46 | #define EP0_MAX_PKT_SIZE 512 | ||
47 | |||
48 | /* 64 entries in a SRR */ | ||
49 | #define NUM_SR_ENTRIES 64 | ||
50 | |||
51 | /* Num of bds per table */ | ||
52 | #define NUM_BDS_PER_TABLE 32 | ||
53 | |||
54 | /* Num of tables in bd list for control,bulk and Int ep */ | ||
55 | #define NUM_TABLES 2 | ||
56 | |||
57 | /* Num of tables in bd list for Isoch ep */ | ||
58 | #define NUM_TABLES_ISOCH 6 | ||
59 | |||
60 | /* U1 Timeout default: 248usec */ | ||
61 | #define U1_TIMEOUT 0xf8 | ||
62 | |||
63 | /* Interrupt coalescence in usec */ | ||
64 | #define INT_CLS 500 | ||
65 | |||
66 | /* Register offsets */ | ||
67 | /* Configuration and Capability registers */ | ||
68 | #define BDC_BDCCFG0 0x00 | ||
69 | #define BDC_BDCCFG1 0x04 | ||
70 | #define BDC_BDCCAP0 0x08 | ||
71 | #define BDC_BDCCAP1 0x0c | ||
72 | #define BDC_CMDPAR0 0x10 | ||
73 | #define BDC_CMDPAR1 0x14 | ||
74 | #define BDC_CMDPAR2 0x18 | ||
75 | #define BDC_CMDSC 0x1c | ||
76 | #define BDC_USPC 0x20 | ||
77 | #define BDC_USPPMS 0x28 | ||
78 | #define BDC_USPPM2 0x2c | ||
79 | #define BDC_SPBBAL 0x38 | ||
80 | #define BDC_SPBBAH 0x3c | ||
81 | #define BDC_BDCSC 0x40 | ||
82 | #define BDC_XSFNTF 0x4c | ||
83 | |||
84 | #define BDC_DVCSA 0x50 | ||
85 | #define BDC_DVCSB 0x54 | ||
86 | #define BDC_EPSTS0(n) (0x60 + (n * 0x10)) | ||
87 | #define BDC_EPSTS1(n) (0x64 + (n * 0x10)) | ||
88 | #define BDC_EPSTS2(n) (0x68 + (n * 0x10)) | ||
89 | #define BDC_EPSTS3(n) (0x6c + (n * 0x10)) | ||
90 | #define BDC_EPSTS4(n) (0x70 + (n * 0x10)) | ||
91 | #define BDC_EPSTS5(n) (0x74 + (n * 0x10)) | ||
92 | #define BDC_EPSTS6(n) (0x78 + (n * 0x10)) | ||
93 | #define BDC_EPSTS7(n) (0x7c + (n * 0x10)) | ||
94 | #define BDC_SRRBAL(n) (0x200 + (n * 0x10)) | ||
95 | #define BDC_SRRBAH(n) (0x204 + (n * 0x10)) | ||
96 | #define BDC_SRRINT(n) (0x208 + (n * 0x10)) | ||
97 | #define BDC_INTCTLS(n) (0x20c + (n * 0x10)) | ||
98 | |||
99 | /* Extended capability regs */ | ||
100 | #define BDC_FSCNOC 0xcd4 | ||
101 | #define BDC_FSCNIC 0xce4 | ||
102 | #define NUM_NCS(p) (p >> 28) | ||
103 | |||
104 | /* Register bit fields and Masks */ | ||
105 | /* BDC Configuration 0 */ | ||
106 | #define BDC_PGS(p) (((p) & (0x7 << 8)) >> 8) | ||
107 | #define BDC_SPB(p) (p & 0x7) | ||
108 | |||
109 | /* BDC Capability1 */ | ||
110 | #define BDC_P64 (1 << 0) | ||
111 | |||
112 | /* BDC Command register */ | ||
113 | #define BDC_CMD_FH 0xe | ||
114 | #define BDC_CMD_DNC 0x6 | ||
115 | #define BDC_CMD_EPO 0x4 | ||
116 | #define BDC_CMD_BLA 0x3 | ||
117 | #define BDC_CMD_EPC 0x2 | ||
118 | #define BDC_CMD_DVC 0x1 | ||
119 | #define BDC_CMD_CWS (0x1 << 5) | ||
120 | #define BDC_CMD_CST(p) (((p) & (0xf << 6))>>6) | ||
121 | #define BDC_CMD_EPN(p) ((p & 0x1f) << 10) | ||
122 | #define BDC_SUB_CMD_ADD (0x1 << 17) | ||
123 | #define BDC_SUB_CMD_FWK (0x4 << 17) | ||
124 | /* Reset sequence number */ | ||
125 | #define BDC_CMD_EPO_RST_SN (0x1 << 16) | ||
126 | #define BDC_CMD_EP0_XSD (0x1 << 16) | ||
127 | #define BDC_SUB_CMD_ADD_EP (0x1 << 17) | ||
128 | #define BDC_SUB_CMD_DRP_EP (0x2 << 17) | ||
129 | #define BDC_SUB_CMD_EP_STP (0x2 << 17) | ||
130 | #define BDC_SUB_CMD_EP_STL (0x4 << 17) | ||
131 | #define BDC_SUB_CMD_EP_RST (0x1 << 17) | ||
132 | #define BDC_CMD_SRD (1 << 27) | ||
133 | |||
134 | /* CMD completion status */ | ||
135 | #define BDC_CMDS_SUCC 0x1 | ||
136 | #define BDC_CMDS_PARA 0x3 | ||
137 | #define BDC_CMDS_STAT 0x4 | ||
138 | #define BDC_CMDS_FAIL 0x5 | ||
139 | #define BDC_CMDS_INTL 0x6 | ||
140 | #define BDC_CMDS_BUSY 0xf | ||
141 | |||
142 | /* CMDSC Param 2 shifts */ | ||
143 | #define EPT_SHIFT 22 | ||
144 | #define MP_SHIFT 10 | ||
145 | #define MB_SHIFT 6 | ||
146 | #define EPM_SHIFT 4 | ||
147 | |||
148 | /* BDC USPSC */ | ||
149 | #define BDC_VBC (1 << 31) | ||
150 | #define BDC_PRC (1 << 30) | ||
151 | #define BDC_PCE (1 << 29) | ||
152 | #define BDC_CFC (1 << 28) | ||
153 | #define BDC_PCC (1 << 27) | ||
154 | #define BDC_PSC (1 << 26) | ||
155 | #define BDC_VBS (1 << 25) | ||
156 | #define BDC_PRS (1 << 24) | ||
157 | #define BDC_PCS (1 << 23) | ||
158 | #define BDC_PSP(p) (((p) & (0x7 << 20))>>20) | ||
159 | #define BDC_SCN (1 << 8) | ||
160 | #define BDC_SDC (1 << 7) | ||
161 | #define BDC_SWS (1 << 4) | ||
162 | |||
163 | #define BDC_USPSC_RW (BDC_SCN|BDC_SDC|BDC_SWS|0xf) | ||
164 | #define BDC_PSP(p) (((p) & (0x7 << 20))>>20) | ||
165 | |||
166 | #define BDC_SPEED_FS 0x1 | ||
167 | #define BDC_SPEED_LS 0x2 | ||
168 | #define BDC_SPEED_HS 0x3 | ||
169 | #define BDC_SPEED_SS 0x4 | ||
170 | |||
171 | #define BDC_PST(p) (p & 0xf) | ||
172 | #define BDC_PST_MASK 0xf | ||
173 | |||
174 | /* USPPMS */ | ||
175 | #define BDC_U2E (0x1 << 31) | ||
176 | #define BDC_U1E (0x1 << 30) | ||
177 | #define BDC_U2A (0x1 << 29) | ||
178 | #define BDC_PORT_W1S (0x1 << 17) | ||
179 | #define BDC_U1T(p) ((p) & 0xff) | ||
180 | #define BDC_U2T(p) (((p) & 0xff) << 8) | ||
181 | #define BDC_U1T_MASK 0xff | ||
182 | |||
183 | /* USBPM2 */ | ||
184 | /* Hardware LPM Enable */ | ||
185 | #define BDC_HLE (1 << 16) | ||
186 | |||
187 | /* BDC Status and Control */ | ||
188 | #define BDC_COP_RST (1 << 29) | ||
189 | #define BDC_COP_RUN (2 << 29) | ||
190 | #define BDC_COP_STP (4 << 29) | ||
191 | |||
192 | #define BDC_COP_MASK (BDC_COP_RST|BDC_COP_RUN|BDC_COP_STP) | ||
193 | |||
194 | #define BDC_COS (1 << 28) | ||
195 | #define BDC_CSTS(p) (((p) & (0x7 << 20)) >> 20) | ||
196 | #define BDC_MASK_MCW (1 << 7) | ||
197 | #define BDC_GIE (1 << 1) | ||
198 | #define BDC_GIP (1 << 0) | ||
199 | |||
200 | #define BDC_HLT 1 | ||
201 | #define BDC_NOR 2 | ||
202 | #define BDC_OIP 7 | ||
203 | |||
204 | /* Buffer descriptor and Status report bit fields and masks */ | ||
205 | #define BD_TYPE_BITMASK (0xf) | ||
206 | #define BD_CHAIN 0xf | ||
207 | |||
208 | #define BD_TFS_SHIFT 4 | ||
209 | #define BD_SOT (1 << 26) | ||
210 | #define BD_EOT (1 << 27) | ||
211 | #define BD_ISP (1 << 29) | ||
212 | #define BD_IOC (1 << 30) | ||
213 | #define BD_SBF (1 << 31) | ||
214 | |||
215 | #define BD_INTR_TARGET(p) (((p) & 0x1f) << 27) | ||
216 | |||
217 | #define BDC_SRR_RWS (1 << 4) | ||
218 | #define BDC_SRR_RST (1 << 3) | ||
219 | #define BDC_SRR_ISR (1 << 2) | ||
220 | #define BDC_SRR_IE (1 << 1) | ||
221 | #define BDC_SRR_IP (1 << 0) | ||
222 | #define BDC_SRR_EPI(p) (((p) & (0xff << 24)) >> 24) | ||
223 | #define BDC_SRR_DPI(p) (((p) & (0xff << 16)) >> 16) | ||
224 | #define BDC_SRR_DPI_MASK 0x00ff0000 | ||
225 | |||
226 | #define MARK_CHAIN_BD (BD_CHAIN|BD_EOT|BD_SOT) | ||
227 | |||
228 | /* Control transfer BD specific fields */ | ||
229 | #define BD_DIR_IN (1 << 25) | ||
230 | |||
231 | #define BDC_PTC_MASK 0xf0000000 | ||
232 | |||
233 | /* status report defines */ | ||
234 | #define SR_XSF 0 | ||
235 | #define SR_USPC 4 | ||
236 | #define SR_BD_LEN(p) (p & 0xffffff) | ||
237 | |||
238 | #define XSF_SUCC 0x1 | ||
239 | #define XSF_SHORT 0x3 | ||
240 | #define XSF_BABB 0x4 | ||
241 | #define XSF_SETUP_RECV 0x6 | ||
242 | #define XSF_DATA_START 0x7 | ||
243 | #define XSF_STATUS_START 0x8 | ||
244 | |||
245 | #define XSF_STS(p) (((p) >> 28) & 0xf) | ||
246 | |||
247 | /* Transfer BD fields */ | ||
248 | #define BD_LEN(p) ((p) & 0x1ffff) | ||
249 | #define BD_LTF (1 << 25) | ||
250 | #define BD_TYPE_DS 0x1 | ||
251 | #define BD_TYPE_SS 0x2 | ||
252 | |||
253 | #define BDC_EP_ENABLED (1 << 0) | ||
254 | #define BDC_EP_STALL (1 << 1) | ||
255 | #define BDC_EP_STOP (1 << 2) | ||
256 | |||
257 | /* One BD can transfer max 65536 bytes */ | ||
258 | #define BD_MAX_BUFF_SIZE (1 << 16) | ||
259 | /* Maximum bytes in one XFR, Refer to BDC spec */ | ||
260 | #define MAX_XFR_LEN 16777215 | ||
261 | |||
262 | /* defines for Force Header command */ | ||
263 | #define DEV_NOTF_TYPE 6 | ||
264 | #define FWK_SUBTYPE 1 | ||
265 | #define TRA_PACKET 4 | ||
266 | |||
267 | #define to_bdc_ep(e) container_of(e, struct bdc_ep, usb_ep) | ||
268 | #define to_bdc_req(r) container_of(r, struct bdc_req, usb_req) | ||
269 | #define gadget_to_bdc(g) container_of(g, struct bdc, gadget) | ||
270 | |||
271 | /* FUNCTION WAKE DEV NOTIFICATION interval, USB3 spec table 8.13 */ | ||
272 | #define BDC_TNOTIFY 2500 /*in ms*/ | ||
273 | /* Devstatus bitfields */ | ||
274 | #define REMOTE_WAKEUP_ISSUED (1 << 16) | ||
275 | #define DEVICE_SUSPENDED (1 << 17) | ||
276 | #define FUNC_WAKE_ISSUED (1 << 18) | ||
277 | #define REMOTE_WAKE_ENABLE (1 << USB_DEVICE_REMOTE_WAKEUP) | ||
278 | |||
279 | /* On disconnect, preserve these bits and clear rest */ | ||
280 | #define DEVSTATUS_CLEAR (1 << USB_DEVICE_SELF_POWERED) | ||
281 | /* Hardware and software Data structures */ | ||
282 | |||
283 | /* Endpoint bd: buffer descriptor */ | ||
284 | struct bdc_bd { | ||
285 | __le32 offset[4]; | ||
286 | }; | ||
287 | |||
288 | /* Status report in Status report ring(srr) */ | ||
289 | struct bdc_sr { | ||
290 | __le32 offset[4]; | ||
291 | }; | ||
292 | |||
293 | /* bd_table: contigous bd's in a table */ | ||
294 | struct bd_table { | ||
295 | struct bdc_bd *start_bd; | ||
296 | /* dma address of start bd of table*/ | ||
297 | dma_addr_t dma; | ||
298 | }; | ||
299 | |||
300 | /* | ||
301 | * Each endpoint has a bdl(buffer descriptor list), bdl consists of 1 or more bd | ||
302 | * table's chained to each other through a chain bd, every table has equal | ||
303 | * number of bds. the software uses bdi(bd index) to refer to particular bd in | ||
304 | * the list. | ||
305 | */ | ||
306 | struct bd_list { | ||
307 | /* Array of bd table pointers*/ | ||
308 | struct bd_table **bd_table_array; | ||
309 | /* How many tables chained to each other */ | ||
310 | int num_tabs; | ||
311 | /* Max_bdi = num_tabs * num_bds_table - 1 */ | ||
312 | int max_bdi; | ||
313 | /* current enq bdi from sw point of view */ | ||
314 | int eqp_bdi; | ||
315 | /* current deq bdi from sw point of view */ | ||
316 | int hwd_bdi; | ||
317 | /* numbers of bds per table */ | ||
318 | int num_bds_table; | ||
319 | }; | ||
320 | |||
321 | struct bdc_req; | ||
322 | |||
323 | /* Representation of a transfer, one transfer can have multiple bd's */ | ||
324 | struct bd_transfer { | ||
325 | struct bdc_req *req; | ||
326 | /* start bd index */ | ||
327 | int start_bdi; | ||
328 | /* this will be the next hw dqp when this transfer completes */ | ||
329 | int next_hwd_bdi; | ||
330 | /* number of bds in this transfer */ | ||
331 | int num_bds; | ||
332 | }; | ||
333 | |||
334 | /* | ||
335 | * Representation of a gadget request, every gadget request is contained | ||
336 | * by 1 bd_transfer. | ||
337 | */ | ||
338 | struct bdc_req { | ||
339 | struct usb_request usb_req; | ||
340 | struct list_head queue; | ||
341 | struct bdc_ep *ep; | ||
342 | /* only one Transfer per request */ | ||
343 | struct bd_transfer bd_xfr; | ||
344 | int epnum; | ||
345 | }; | ||
346 | |||
347 | /* scratchpad buffer needed by bdc hardware */ | ||
348 | struct bdc_scratchpad { | ||
349 | dma_addr_t sp_dma; | ||
350 | void *buff; | ||
351 | u32 size; | ||
352 | }; | ||
353 | |||
354 | /* endpoint representation */ | ||
355 | struct bdc_ep { | ||
356 | struct usb_ep usb_ep; | ||
357 | struct list_head queue; | ||
358 | struct bdc *bdc; | ||
359 | u8 ep_type; | ||
360 | u8 dir; | ||
361 | u8 ep_num; | ||
362 | const struct usb_ss_ep_comp_descriptor *comp_desc; | ||
363 | const struct usb_endpoint_descriptor *desc; | ||
364 | unsigned int flags; | ||
365 | char name[20]; | ||
366 | /* endpoint bd list*/ | ||
367 | struct bd_list bd_list; | ||
368 | /* | ||
369 | * HW generates extra event for multi bd tranfers, this flag helps in | ||
370 | * ignoring the extra event | ||
371 | */ | ||
372 | bool ignore_next_sr; | ||
373 | }; | ||
374 | |||
375 | /* bdc cmmand parameter structure */ | ||
376 | struct bdc_cmd_params { | ||
377 | u32 param2; | ||
378 | u32 param1; | ||
379 | u32 param0; | ||
380 | }; | ||
381 | |||
382 | /* status report ring(srr), currently one srr is supported for entire system */ | ||
383 | struct srr { | ||
384 | struct bdc_sr *sr_bds; | ||
385 | u16 eqp_index; | ||
386 | u16 dqp_index; | ||
387 | dma_addr_t dma_addr; | ||
388 | }; | ||
389 | |||
390 | /* EP0 states */ | ||
391 | enum bdc_ep0_state { | ||
392 | WAIT_FOR_SETUP = 0, | ||
393 | WAIT_FOR_DATA_START, | ||
394 | WAIT_FOR_DATA_XMIT, | ||
395 | WAIT_FOR_STATUS_START, | ||
396 | WAIT_FOR_STATUS_XMIT, | ||
397 | STATUS_PENDING | ||
398 | }; | ||
399 | |||
400 | /* Link states */ | ||
401 | enum bdc_link_state { | ||
402 | BDC_LINK_STATE_U0 = 0x00, | ||
403 | BDC_LINK_STATE_U3 = 0x03, | ||
404 | BDC_LINK_STATE_RX_DET = 0x05, | ||
405 | BDC_LINK_STATE_RESUME = 0x0f | ||
406 | }; | ||
407 | |||
408 | /* representation of bdc */ | ||
409 | struct bdc { | ||
410 | struct usb_gadget gadget; | ||
411 | struct usb_gadget_driver *gadget_driver; | ||
412 | struct device *dev; | ||
413 | /* device lock */ | ||
414 | spinlock_t lock; | ||
415 | |||
416 | /* num of endpoints for a particular instantiation of IP */ | ||
417 | unsigned int num_eps; | ||
418 | /* | ||
419 | * Array of ep's, it uses the same index covention as bdc hw i.e. | ||
420 | * 1 for ep0, 2 for 1out,3 for 1in .... | ||
421 | */ | ||
422 | struct bdc_ep **bdc_ep_array; | ||
423 | void __iomem *regs; | ||
424 | struct bdc_scratchpad scratchpad; | ||
425 | u32 sp_buff_size; | ||
426 | /* current driver supports 1 status ring */ | ||
427 | struct srr srr; | ||
428 | /* Last received setup packet */ | ||
429 | struct usb_ctrlrequest setup_pkt; | ||
430 | struct bdc_req ep0_req; | ||
431 | struct bdc_req status_req; | ||
432 | enum bdc_ep0_state ep0_state; | ||
433 | bool delayed_status; | ||
434 | bool zlp_needed; | ||
435 | bool reinit; | ||
436 | bool pullup; | ||
437 | /* Bits 0-15 are standard and 16-31 for proprietary information */ | ||
438 | u32 devstatus; | ||
439 | int irq; | ||
440 | void *mem; | ||
441 | u32 dev_addr; | ||
442 | /* DMA pools */ | ||
443 | struct dma_pool *bd_table_pool; | ||
444 | u8 test_mode; | ||
445 | /* array of callbacks for various status report handlers */ | ||
446 | void (*sr_handler[2])(struct bdc *, struct bdc_sr *); | ||
447 | /* ep0 callback handlers */ | ||
448 | void (*sr_xsf_ep0[3])(struct bdc *, struct bdc_sr *); | ||
449 | /* ep0 response buffer for ch9 requests like GET_STATUS and SET_SEL */ | ||
450 | unsigned char ep0_response_buff[EP0_RESPONSE_BUFF]; | ||
451 | /* | ||
452 | * Timer to check if host resumed transfer after bdc sent Func wake | ||
453 | * notification packet after a remote wakeup. if not, then resend the | ||
454 | * Func Wake packet every 2.5 secs. Refer to USB3 spec section 8.5.6.4 | ||
455 | */ | ||
456 | struct delayed_work func_wake_notify; | ||
457 | }; | ||
458 | |||
459 | static inline u32 bdc_readl(void __iomem *base, u32 offset) | ||
460 | { | ||
461 | return readl(base + offset); | ||
462 | } | ||
463 | |||
464 | static inline void bdc_writel(void __iomem *base, u32 offset, u32 value) | ||
465 | { | ||
466 | writel(value, base + offset); | ||
467 | } | ||
468 | |||
469 | /* Buffer descriptor list operations */ | ||
470 | void bdc_notify_xfr(struct bdc *, u32); | ||
471 | void bdc_softconn(struct bdc *); | ||
472 | void bdc_softdisconn(struct bdc *); | ||
473 | int bdc_run(struct bdc *); | ||
474 | int bdc_stop(struct bdc *); | ||
475 | int bdc_reset(struct bdc *); | ||
476 | int bdc_udc_init(struct bdc *); | ||
477 | void bdc_udc_exit(struct bdc *); | ||
478 | int bdc_reinit(struct bdc *); | ||
479 | |||
480 | /* Status report handlers */ | ||
481 | /* Upstream port status change sr */ | ||
482 | void bdc_sr_uspc(struct bdc *, struct bdc_sr *); | ||
483 | /* transfer sr */ | ||
484 | void bdc_sr_xsf(struct bdc *, struct bdc_sr *); | ||
485 | /* EP0 XSF handlers */ | ||
486 | void bdc_xsf_ep0_setup_recv(struct bdc *, struct bdc_sr *); | ||
487 | void bdc_xsf_ep0_data_start(struct bdc *, struct bdc_sr *); | ||
488 | void bdc_xsf_ep0_status_start(struct bdc *, struct bdc_sr *); | ||
489 | |||
490 | #endif /* __LINUX_BDC_H__ */ | ||
diff --git a/drivers/usb/gadget/udc/bdc/bdc_cmd.c b/drivers/usb/gadget/udc/bdc/bdc_cmd.c new file mode 100644 index 000000000000..6a4155c4bd86 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_cmd.c | |||
@@ -0,0 +1,376 @@ | |||
1 | /* | ||
2 | * bdc_cmd.c - BRCM BDC USB3.0 device controller | ||
3 | * | ||
4 | * Copyright (C) 2014 Broadcom Corporation | ||
5 | * | ||
6 | * Author: Ashwini Pahuja | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/scatterlist.h> | ||
15 | #include <linux/slab.h> | ||
16 | |||
17 | #include "bdc.h" | ||
18 | #include "bdc_cmd.h" | ||
19 | #include "bdc_dbg.h" | ||
20 | |||
21 | /* Issues a cmd to cmd processor and waits for cmd completion */ | ||
22 | static int bdc_issue_cmd(struct bdc *bdc, u32 cmd_sc, u32 param0, | ||
23 | u32 param1, u32 param2) | ||
24 | { | ||
25 | u32 timeout = BDC_CMD_TIMEOUT; | ||
26 | u32 cmd_status; | ||
27 | u32 temp; | ||
28 | |||
29 | bdc_writel(bdc->regs, BDC_CMDPAR0, param0); | ||
30 | bdc_writel(bdc->regs, BDC_CMDPAR1, param1); | ||
31 | bdc_writel(bdc->regs, BDC_CMDPAR2, param2); | ||
32 | |||
33 | /* Issue the cmd */ | ||
34 | /* Make sure the cmd params are written before asking HW to exec cmd */ | ||
35 | wmb(); | ||
36 | bdc_writel(bdc->regs, BDC_CMDSC, cmd_sc | BDC_CMD_CWS | BDC_CMD_SRD); | ||
37 | do { | ||
38 | temp = bdc_readl(bdc->regs, BDC_CMDSC); | ||
39 | dev_dbg_ratelimited(bdc->dev, "cmdsc=%x", temp); | ||
40 | cmd_status = BDC_CMD_CST(temp); | ||
41 | if (cmd_status != BDC_CMDS_BUSY) { | ||
42 | dev_dbg(bdc->dev, | ||
43 | "command completed cmd_sts:%x\n", cmd_status); | ||
44 | return cmd_status; | ||
45 | } | ||
46 | udelay(1); | ||
47 | } while (timeout--); | ||
48 | |||
49 | dev_err(bdc->dev, | ||
50 | "command operation timedout cmd_status=%d\n", cmd_status); | ||
51 | |||
52 | return cmd_status; | ||
53 | } | ||
54 | |||
55 | /* Submits cmd and analyze the return value of bdc_issue_cmd */ | ||
56 | static int bdc_submit_cmd(struct bdc *bdc, u32 cmd_sc, | ||
57 | u32 param0, u32 param1, u32 param2) | ||
58 | { | ||
59 | u32 temp, cmd_status; | ||
60 | int reset_bdc = 0; | ||
61 | int ret; | ||
62 | |||
63 | temp = bdc_readl(bdc->regs, BDC_CMDSC); | ||
64 | dev_dbg(bdc->dev, | ||
65 | "%s:CMDSC:%08x cmdsc:%08x param0=%08x param1=%08x param2=%08x\n", | ||
66 | __func__, temp, cmd_sc, param0, param1, param2); | ||
67 | |||
68 | cmd_status = BDC_CMD_CST(temp); | ||
69 | if (cmd_status == BDC_CMDS_BUSY) { | ||
70 | dev_err(bdc->dev, "command processor busy: %x\n", cmd_status); | ||
71 | return -EBUSY; | ||
72 | } | ||
73 | ret = bdc_issue_cmd(bdc, cmd_sc, param0, param1, param2); | ||
74 | switch (ret) { | ||
75 | case BDC_CMDS_SUCC: | ||
76 | dev_dbg(bdc->dev, "command completed successfully\n"); | ||
77 | ret = 0; | ||
78 | break; | ||
79 | |||
80 | case BDC_CMDS_PARA: | ||
81 | dev_err(bdc->dev, "command parameter error\n"); | ||
82 | ret = -EINVAL; | ||
83 | break; | ||
84 | |||
85 | case BDC_CMDS_STAT: | ||
86 | dev_err(bdc->dev, "Invalid device/ep state\n"); | ||
87 | ret = -EINVAL; | ||
88 | break; | ||
89 | |||
90 | case BDC_CMDS_FAIL: | ||
91 | dev_err(bdc->dev, "Command failed?\n"); | ||
92 | ret = -EAGAIN; | ||
93 | break; | ||
94 | |||
95 | case BDC_CMDS_INTL: | ||
96 | dev_err(bdc->dev, "BDC Internal error\n"); | ||
97 | reset_bdc = 1; | ||
98 | ret = -ECONNRESET; | ||
99 | break; | ||
100 | |||
101 | case BDC_CMDS_BUSY: | ||
102 | dev_err(bdc->dev, | ||
103 | "command timedout waited for %dusec\n", | ||
104 | BDC_CMD_TIMEOUT); | ||
105 | reset_bdc = 1; | ||
106 | ret = -ECONNRESET; | ||
107 | break; | ||
108 | default: | ||
109 | dev_dbg(bdc->dev, "Unknown command completion code:%x\n", ret); | ||
110 | } | ||
111 | |||
112 | return ret; | ||
113 | } | ||
114 | |||
115 | /* Deconfigure the endpoint from HW */ | ||
116 | int bdc_dconfig_ep(struct bdc *bdc, struct bdc_ep *ep) | ||
117 | { | ||
118 | u32 cmd_sc; | ||
119 | |||
120 | cmd_sc = BDC_SUB_CMD_DRP_EP|BDC_CMD_EPN(ep->ep_num)|BDC_CMD_EPC; | ||
121 | dev_dbg(bdc->dev, "%s ep->ep_num =%d cmd_sc=%x\n", __func__, | ||
122 | ep->ep_num, cmd_sc); | ||
123 | |||
124 | return bdc_submit_cmd(bdc, cmd_sc, 0, 0, 0); | ||
125 | } | ||
126 | |||
127 | /* Reinitalize the bdlist after config ep command */ | ||
128 | static void ep_bd_list_reinit(struct bdc_ep *ep) | ||
129 | { | ||
130 | struct bdc *bdc = ep->bdc; | ||
131 | struct bdc_bd *bd; | ||
132 | |||
133 | ep->bd_list.eqp_bdi = 0; | ||
134 | ep->bd_list.hwd_bdi = 0; | ||
135 | bd = ep->bd_list.bd_table_array[0]->start_bd; | ||
136 | dev_dbg(bdc->dev, "%s ep:%p bd:%p\n", __func__, ep, bd); | ||
137 | memset(bd, 0, sizeof(struct bdc_bd)); | ||
138 | bd->offset[3] |= cpu_to_le32(BD_SBF); | ||
139 | } | ||
140 | |||
141 | /* Configure an endpoint */ | ||
142 | int bdc_config_ep(struct bdc *bdc, struct bdc_ep *ep) | ||
143 | { | ||
144 | const struct usb_ss_ep_comp_descriptor *comp_desc; | ||
145 | const struct usb_endpoint_descriptor *desc; | ||
146 | u32 param0, param1, param2, cmd_sc; | ||
147 | u32 mps, mbs, mul, si; | ||
148 | int ret; | ||
149 | |||
150 | desc = ep->desc; | ||
151 | comp_desc = ep->comp_desc; | ||
152 | cmd_sc = mul = mbs = param2 = 0; | ||
153 | param0 = lower_32_bits(ep->bd_list.bd_table_array[0]->dma); | ||
154 | param1 = upper_32_bits(ep->bd_list.bd_table_array[0]->dma); | ||
155 | cpu_to_le32s(¶m0); | ||
156 | cpu_to_le32s(¶m1); | ||
157 | |||
158 | dev_dbg(bdc->dev, "%s: param0=%08x param1=%08x", | ||
159 | __func__, param0, param1); | ||
160 | si = desc->bInterval; | ||
161 | si = clamp_val(si, 1, 16) - 1; | ||
162 | |||
163 | mps = usb_endpoint_maxp(desc); | ||
164 | mps &= 0x7ff; | ||
165 | param2 |= mps << MP_SHIFT; | ||
166 | param2 |= usb_endpoint_type(desc) << EPT_SHIFT; | ||
167 | |||
168 | switch (bdc->gadget.speed) { | ||
169 | case USB_SPEED_SUPER: | ||
170 | if (usb_endpoint_xfer_int(desc) || | ||
171 | usb_endpoint_xfer_isoc(desc)) { | ||
172 | param2 |= si; | ||
173 | if (usb_endpoint_xfer_isoc(desc) && comp_desc) | ||
174 | mul = comp_desc->bmAttributes; | ||
175 | |||
176 | } | ||
177 | param2 |= mul << EPM_SHIFT; | ||
178 | if (comp_desc) | ||
179 | mbs = comp_desc->bMaxBurst; | ||
180 | param2 |= mbs << MB_SHIFT; | ||
181 | break; | ||
182 | |||
183 | case USB_SPEED_HIGH: | ||
184 | if (usb_endpoint_xfer_isoc(desc) || | ||
185 | usb_endpoint_xfer_int(desc)) { | ||
186 | param2 |= si; | ||
187 | |||
188 | mbs = (usb_endpoint_maxp(desc) & 0x1800) >> 11; | ||
189 | param2 |= mbs << MB_SHIFT; | ||
190 | } | ||
191 | break; | ||
192 | |||
193 | case USB_SPEED_FULL: | ||
194 | case USB_SPEED_LOW: | ||
195 | /* the hardware accepts SI in 125usec range */ | ||
196 | if (usb_endpoint_xfer_isoc(desc)) | ||
197 | si += 3; | ||
198 | |||
199 | /* | ||
200 | * FS Int endpoints can have si of 1-255ms but the controller | ||
201 | * accepts 2^bInterval*125usec, so convert ms to nearest power | ||
202 | * of 2 | ||
203 | */ | ||
204 | if (usb_endpoint_xfer_int(desc)) | ||
205 | si = fls(desc->bInterval * 8) - 1; | ||
206 | |||
207 | param2 |= si; | ||
208 | break; | ||
209 | default: | ||
210 | dev_err(bdc->dev, "UNKNOWN speed ERR\n"); | ||
211 | return -EINVAL; | ||
212 | } | ||
213 | |||
214 | cmd_sc |= BDC_CMD_EPC|BDC_CMD_EPN(ep->ep_num)|BDC_SUB_CMD_ADD_EP; | ||
215 | |||
216 | dev_dbg(bdc->dev, "cmd_sc=%x param2=%08x\n", cmd_sc, param2); | ||
217 | ret = bdc_submit_cmd(bdc, cmd_sc, param0, param1, param2); | ||
218 | if (ret) { | ||
219 | dev_err(bdc->dev, "command failed :%x\n", ret); | ||
220 | return ret; | ||
221 | } | ||
222 | ep_bd_list_reinit(ep); | ||
223 | |||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | /* | ||
228 | * Change the HW deq pointer, if this command is successful, HW will start | ||
229 | * fetching the next bd from address dma_addr. | ||
230 | */ | ||
231 | int bdc_ep_bla(struct bdc *bdc, struct bdc_ep *ep, dma_addr_t dma_addr) | ||
232 | { | ||
233 | u32 param0, param1; | ||
234 | u32 cmd_sc = 0; | ||
235 | |||
236 | dev_dbg(bdc->dev, "%s: add=%08llx\n", __func__, | ||
237 | (unsigned long long)(dma_addr)); | ||
238 | param0 = lower_32_bits(dma_addr); | ||
239 | param1 = upper_32_bits(dma_addr); | ||
240 | cpu_to_le32s(¶m0); | ||
241 | cpu_to_le32s(¶m1); | ||
242 | |||
243 | cmd_sc |= BDC_CMD_EPN(ep->ep_num)|BDC_CMD_BLA; | ||
244 | dev_dbg(bdc->dev, "cmd_sc=%x\n", cmd_sc); | ||
245 | |||
246 | return bdc_submit_cmd(bdc, cmd_sc, param0, param1, 0); | ||
247 | } | ||
248 | |||
249 | /* Set the address sent bu Host in SET_ADD request */ | ||
250 | int bdc_address_device(struct bdc *bdc, u32 add) | ||
251 | { | ||
252 | u32 cmd_sc = 0; | ||
253 | u32 param2; | ||
254 | |||
255 | dev_dbg(bdc->dev, "%s: add=%d\n", __func__, add); | ||
256 | cmd_sc |= BDC_SUB_CMD_ADD|BDC_CMD_DVC; | ||
257 | param2 = add & 0x7f; | ||
258 | |||
259 | return bdc_submit_cmd(bdc, cmd_sc, 0, 0, param2); | ||
260 | } | ||
261 | |||
262 | /* Send a Function Wake notification packet using FH command */ | ||
263 | int bdc_function_wake_fh(struct bdc *bdc, u8 intf) | ||
264 | { | ||
265 | u32 param0, param1; | ||
266 | u32 cmd_sc = 0; | ||
267 | |||
268 | param0 = param1 = 0; | ||
269 | dev_dbg(bdc->dev, "%s intf=%d\n", __func__, intf); | ||
270 | cmd_sc |= BDC_CMD_FH; | ||
271 | param0 |= TRA_PACKET; | ||
272 | param0 |= (bdc->dev_addr << 25); | ||
273 | param1 |= DEV_NOTF_TYPE; | ||
274 | param1 |= (FWK_SUBTYPE<<4); | ||
275 | dev_dbg(bdc->dev, "param0=%08x param1=%08x\n", param0, param1); | ||
276 | |||
277 | return bdc_submit_cmd(bdc, cmd_sc, param0, param1, 0); | ||
278 | } | ||
279 | |||
280 | /* Send a Function Wake notification packet using DNC command */ | ||
281 | int bdc_function_wake(struct bdc *bdc, u8 intf) | ||
282 | { | ||
283 | u32 cmd_sc = 0; | ||
284 | u32 param2 = 0; | ||
285 | |||
286 | dev_dbg(bdc->dev, "%s intf=%d", __func__, intf); | ||
287 | param2 |= intf; | ||
288 | cmd_sc |= BDC_SUB_CMD_FWK|BDC_CMD_DNC; | ||
289 | |||
290 | return bdc_submit_cmd(bdc, cmd_sc, 0, 0, param2); | ||
291 | } | ||
292 | |||
293 | /* Stall the endpoint */ | ||
294 | int bdc_ep_set_stall(struct bdc *bdc, int epnum) | ||
295 | { | ||
296 | u32 cmd_sc = 0; | ||
297 | |||
298 | dev_dbg(bdc->dev, "%s epnum=%d\n", __func__, epnum); | ||
299 | /* issue a stall endpoint command */ | ||
300 | cmd_sc |= BDC_SUB_CMD_EP_STL | BDC_CMD_EPN(epnum) | BDC_CMD_EPO; | ||
301 | |||
302 | return bdc_submit_cmd(bdc, cmd_sc, 0, 0, 0); | ||
303 | } | ||
304 | |||
305 | /* resets the endpoint, called when host sends CLEAR_FEATURE(HALT) */ | ||
306 | int bdc_ep_clear_stall(struct bdc *bdc, int epnum) | ||
307 | { | ||
308 | struct bdc_ep *ep; | ||
309 | u32 cmd_sc = 0; | ||
310 | int ret; | ||
311 | |||
312 | dev_dbg(bdc->dev, "%s: epnum=%d\n", __func__, epnum); | ||
313 | ep = bdc->bdc_ep_array[epnum]; | ||
314 | /* | ||
315 | * If we are not in stalled then stall Endpoint and issue clear stall, | ||
316 | * his will reset the seq number for non EP0. | ||
317 | */ | ||
318 | if (epnum != 1) { | ||
319 | /* if the endpoint it not stallled */ | ||
320 | if (!(ep->flags & BDC_EP_STALL)) { | ||
321 | ret = bdc_ep_set_stall(bdc, epnum); | ||
322 | if (ret) | ||
323 | return ret; | ||
324 | } | ||
325 | } | ||
326 | /* Preserve the seq number for ep0 only */ | ||
327 | if (epnum != 1) | ||
328 | cmd_sc |= BDC_CMD_EPO_RST_SN; | ||
329 | |||
330 | /* issue a reset endpoint command */ | ||
331 | cmd_sc |= BDC_SUB_CMD_EP_RST | BDC_CMD_EPN(epnum) | BDC_CMD_EPO; | ||
332 | |||
333 | ret = bdc_submit_cmd(bdc, cmd_sc, 0, 0, 0); | ||
334 | if (ret) { | ||
335 | dev_err(bdc->dev, "command failed:%x\n", ret); | ||
336 | return ret; | ||
337 | } | ||
338 | bdc_notify_xfr(bdc, epnum); | ||
339 | |||
340 | return ret; | ||
341 | } | ||
342 | |||
343 | /* Stop the endpoint, called when software wants to dequeue some request */ | ||
344 | int bdc_stop_ep(struct bdc *bdc, int epnum) | ||
345 | { | ||
346 | struct bdc_ep *ep; | ||
347 | u32 cmd_sc = 0; | ||
348 | int ret; | ||
349 | |||
350 | ep = bdc->bdc_ep_array[epnum]; | ||
351 | dev_dbg(bdc->dev, "%s: ep:%s ep->flags:%08x\n", __func__, | ||
352 | ep->name, ep->flags); | ||
353 | /* Endpoint has to be in running state to execute stop ep command */ | ||
354 | if (!(ep->flags & BDC_EP_ENABLED)) { | ||
355 | dev_err(bdc->dev, "stop endpoint called for disabled ep\n"); | ||
356 | return -EINVAL; | ||
357 | } | ||
358 | if ((ep->flags & BDC_EP_STALL) || (ep->flags & BDC_EP_STOP)) | ||
359 | return 0; | ||
360 | |||
361 | /* issue a stop endpoint command */ | ||
362 | cmd_sc |= BDC_CMD_EP0_XSD | BDC_SUB_CMD_EP_STP | ||
363 | | BDC_CMD_EPN(epnum) | BDC_CMD_EPO; | ||
364 | |||
365 | ret = bdc_submit_cmd(bdc, cmd_sc, 0, 0, 0); | ||
366 | if (ret) { | ||
367 | dev_err(bdc->dev, | ||
368 | "stop endpoint command didn't complete:%d ep:%s\n", | ||
369 | ret, ep->name); | ||
370 | return ret; | ||
371 | } | ||
372 | ep->flags |= BDC_EP_STOP; | ||
373 | bdc_dump_epsts(bdc); | ||
374 | |||
375 | return ret; | ||
376 | } | ||
diff --git a/drivers/usb/gadget/udc/bdc/bdc_cmd.h b/drivers/usb/gadget/udc/bdc/bdc_cmd.h new file mode 100644 index 000000000000..61d0e3bf9853 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_cmd.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * bdc_cmd.h - header for the BDC debug functions | ||
3 | * | ||
4 | * Copyright (C) 2014 Broadcom Corporation | ||
5 | * | ||
6 | * Author: Ashwini Pahuja | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | #ifndef __LINUX_BDC_CMD_H__ | ||
15 | #define __LINUX_BDC_CMD_H__ | ||
16 | |||
17 | /* Command operations */ | ||
18 | int bdc_address_device(struct bdc *, u32); | ||
19 | int bdc_config_ep(struct bdc *, struct bdc_ep *); | ||
20 | int bdc_dconfig_ep(struct bdc *, struct bdc_ep *); | ||
21 | int bdc_stop_ep(struct bdc *, int); | ||
22 | int bdc_ep_set_stall(struct bdc *, int); | ||
23 | int bdc_ep_clear_stall(struct bdc *, int); | ||
24 | int bdc_ep_set_halt(struct bdc_ep *, u32 , int); | ||
25 | int bdc_ep_bla(struct bdc *, struct bdc_ep *, dma_addr_t); | ||
26 | int bdc_function_wake(struct bdc*, u8); | ||
27 | int bdc_function_wake_fh(struct bdc*, u8); | ||
28 | |||
29 | #endif /* __LINUX_BDC_CMD_H__ */ | ||
diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c new file mode 100644 index 000000000000..c6dfef8c7bbc --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c | |||
@@ -0,0 +1,533 @@ | |||
1 | /* | ||
2 | * bdc_core.c - BRCM BDC USB3.0 device controller core operations | ||
3 | * | ||
4 | * Copyright (C) 2014 Broadcom Corporation | ||
5 | * | ||
6 | * Author: Ashwini Pahuja | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/ioport.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/list.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/dma-mapping.h> | ||
25 | #include <linux/dmapool.h> | ||
26 | #include <linux/of.h> | ||
27 | #include <linux/moduleparam.h> | ||
28 | #include <linux/usb/ch9.h> | ||
29 | #include <linux/usb/gadget.h> | ||
30 | |||
31 | #include "bdc.h" | ||
32 | #include "bdc_dbg.h" | ||
33 | |||
34 | /* Poll till controller status is not OIP */ | ||
35 | static int poll_oip(struct bdc *bdc, int usec) | ||
36 | { | ||
37 | u32 status; | ||
38 | /* Poll till STS!= OIP */ | ||
39 | while (usec) { | ||
40 | status = bdc_readl(bdc->regs, BDC_BDCSC); | ||
41 | if (BDC_CSTS(status) != BDC_OIP) { | ||
42 | dev_dbg(bdc->dev, | ||
43 | "poll_oip complete status=%d", | ||
44 | BDC_CSTS(status)); | ||
45 | return 0; | ||
46 | } | ||
47 | udelay(10); | ||
48 | usec -= 10; | ||
49 | } | ||
50 | dev_err(bdc->dev, "Err: operation timedout BDCSC: 0x%08x\n", status); | ||
51 | |||
52 | return -ETIMEDOUT; | ||
53 | } | ||
54 | |||
55 | /* Stop the BDC controller */ | ||
56 | int bdc_stop(struct bdc *bdc) | ||
57 | { | ||
58 | int ret; | ||
59 | u32 temp; | ||
60 | |||
61 | dev_dbg(bdc->dev, "%s ()\n\n", __func__); | ||
62 | temp = bdc_readl(bdc->regs, BDC_BDCSC); | ||
63 | /* Check if BDC is already halted */ | ||
64 | if (BDC_CSTS(temp) == BDC_HLT) { | ||
65 | dev_vdbg(bdc->dev, "BDC already halted\n"); | ||
66 | return 0; | ||
67 | } | ||
68 | temp &= ~BDC_COP_MASK; | ||
69 | temp |= BDC_COS|BDC_COP_STP; | ||
70 | bdc_writel(bdc->regs, BDC_BDCSC, temp); | ||
71 | |||
72 | ret = poll_oip(bdc, BDC_COP_TIMEOUT); | ||
73 | if (ret) | ||
74 | dev_err(bdc->dev, "bdc stop operation failed"); | ||
75 | |||
76 | return ret; | ||
77 | } | ||
78 | |||
79 | /* Issue a reset to BDC controller */ | ||
80 | int bdc_reset(struct bdc *bdc) | ||
81 | { | ||
82 | u32 temp; | ||
83 | int ret; | ||
84 | |||
85 | dev_dbg(bdc->dev, "%s ()\n", __func__); | ||
86 | /* First halt the controller */ | ||
87 | ret = bdc_stop(bdc); | ||
88 | if (ret) | ||
89 | return ret; | ||
90 | |||
91 | temp = bdc_readl(bdc->regs, BDC_BDCSC); | ||
92 | temp &= ~BDC_COP_MASK; | ||
93 | temp |= BDC_COS|BDC_COP_RST; | ||
94 | bdc_writel(bdc->regs, BDC_BDCSC, temp); | ||
95 | ret = poll_oip(bdc, BDC_COP_TIMEOUT); | ||
96 | if (ret) | ||
97 | dev_err(bdc->dev, "bdc reset operation failed"); | ||
98 | |||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | /* Run the BDC controller */ | ||
103 | int bdc_run(struct bdc *bdc) | ||
104 | { | ||
105 | u32 temp; | ||
106 | int ret; | ||
107 | |||
108 | dev_dbg(bdc->dev, "%s ()\n", __func__); | ||
109 | temp = bdc_readl(bdc->regs, BDC_BDCSC); | ||
110 | /* if BDC is already in running state then do not do anything */ | ||
111 | if (BDC_CSTS(temp) == BDC_NOR) { | ||
112 | dev_warn(bdc->dev, "bdc is already in running state\n"); | ||
113 | return 0; | ||
114 | } | ||
115 | temp &= ~BDC_COP_MASK; | ||
116 | temp |= BDC_COP_RUN; | ||
117 | temp |= BDC_COS; | ||
118 | bdc_writel(bdc->regs, BDC_BDCSC, temp); | ||
119 | ret = poll_oip(bdc, BDC_COP_TIMEOUT); | ||
120 | if (ret) { | ||
121 | dev_err(bdc->dev, "bdc run operation failed:%d", ret); | ||
122 | return ret; | ||
123 | } | ||
124 | temp = bdc_readl(bdc->regs, BDC_BDCSC); | ||
125 | if (BDC_CSTS(temp) != BDC_NOR) { | ||
126 | dev_err(bdc->dev, "bdc not in normal mode after RUN op :%d\n", | ||
127 | BDC_CSTS(temp)); | ||
128 | return -ESHUTDOWN; | ||
129 | } | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * Present the termination to the host, typically called from upstream port | ||
136 | * event with Vbus present =1 | ||
137 | */ | ||
138 | void bdc_softconn(struct bdc *bdc) | ||
139 | { | ||
140 | u32 uspc; | ||
141 | |||
142 | uspc = bdc_readl(bdc->regs, BDC_USPC); | ||
143 | uspc &= ~BDC_PST_MASK; | ||
144 | uspc |= BDC_LINK_STATE_RX_DET; | ||
145 | uspc |= BDC_SWS; | ||
146 | dev_dbg(bdc->dev, "%s () uspc=%08x\n", __func__, uspc); | ||
147 | bdc_writel(bdc->regs, BDC_USPC, uspc); | ||
148 | } | ||
149 | |||
150 | /* Remove the termination */ | ||
151 | void bdc_softdisconn(struct bdc *bdc) | ||
152 | { | ||
153 | u32 uspc; | ||
154 | |||
155 | uspc = bdc_readl(bdc->regs, BDC_USPC); | ||
156 | uspc |= BDC_SDC; | ||
157 | uspc &= ~BDC_SCN; | ||
158 | dev_dbg(bdc->dev, "%s () uspc=%x\n", __func__, uspc); | ||
159 | bdc_writel(bdc->regs, BDC_USPC, uspc); | ||
160 | } | ||
161 | |||
162 | /* Set up the scratchpad buffer array and scratchpad buffers, if needed. */ | ||
163 | static int scratchpad_setup(struct bdc *bdc) | ||
164 | { | ||
165 | int sp_buff_size; | ||
166 | u32 low32; | ||
167 | u32 upp32; | ||
168 | |||
169 | sp_buff_size = BDC_SPB(bdc_readl(bdc->regs, BDC_BDCCFG0)); | ||
170 | dev_dbg(bdc->dev, "%s() sp_buff_size=%d\n", __func__, sp_buff_size); | ||
171 | if (!sp_buff_size) { | ||
172 | dev_dbg(bdc->dev, "Scratchpad buffer not needed\n"); | ||
173 | return 0; | ||
174 | } | ||
175 | /* Refer to BDC spec, Table 4 for description of SPB */ | ||
176 | sp_buff_size = 1 << (sp_buff_size + 5); | ||
177 | dev_dbg(bdc->dev, "Allocating %d bytes for scratchpad\n", sp_buff_size); | ||
178 | bdc->scratchpad.buff = dma_zalloc_coherent(bdc->dev, sp_buff_size, | ||
179 | &bdc->scratchpad.sp_dma, GFP_KERNEL); | ||
180 | |||
181 | if (!bdc->scratchpad.buff) | ||
182 | goto fail; | ||
183 | |||
184 | bdc->sp_buff_size = sp_buff_size; | ||
185 | bdc->scratchpad.size = sp_buff_size; | ||
186 | low32 = lower_32_bits(bdc->scratchpad.sp_dma); | ||
187 | upp32 = upper_32_bits(bdc->scratchpad.sp_dma); | ||
188 | cpu_to_le32s(&low32); | ||
189 | cpu_to_le32s(&upp32); | ||
190 | bdc_writel(bdc->regs, BDC_SPBBAL, low32); | ||
191 | bdc_writel(bdc->regs, BDC_SPBBAH, upp32); | ||
192 | return 0; | ||
193 | |||
194 | fail: | ||
195 | bdc->scratchpad.buff = NULL; | ||
196 | |||
197 | return -ENOMEM; | ||
198 | } | ||
199 | |||
200 | /* Allocate the status report ring */ | ||
201 | static int setup_srr(struct bdc *bdc, int interrupter) | ||
202 | { | ||
203 | dev_dbg(bdc->dev, "%s() NUM_SR_ENTRIES:%d\n", __func__, NUM_SR_ENTRIES); | ||
204 | /* Reset the SRR */ | ||
205 | bdc_writel(bdc->regs, BDC_SRRINT(0), BDC_SRR_RWS | BDC_SRR_RST); | ||
206 | bdc->srr.dqp_index = 0; | ||
207 | /* allocate the status report descriptors */ | ||
208 | bdc->srr.sr_bds = dma_zalloc_coherent( | ||
209 | bdc->dev, | ||
210 | NUM_SR_ENTRIES * sizeof(struct bdc_bd), | ||
211 | &bdc->srr.dma_addr, | ||
212 | GFP_KERNEL); | ||
213 | if (!bdc->srr.sr_bds) | ||
214 | return -ENOMEM; | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | /* Initialize the HW regs and internal data structures */ | ||
220 | static void bdc_mem_init(struct bdc *bdc, bool reinit) | ||
221 | { | ||
222 | u8 size = 0; | ||
223 | u32 usb2_pm; | ||
224 | u32 low32; | ||
225 | u32 upp32; | ||
226 | u32 temp; | ||
227 | |||
228 | dev_dbg(bdc->dev, "%s ()\n", __func__); | ||
229 | bdc->ep0_state = WAIT_FOR_SETUP; | ||
230 | bdc->dev_addr = 0; | ||
231 | bdc->srr.eqp_index = 0; | ||
232 | bdc->srr.dqp_index = 0; | ||
233 | bdc->zlp_needed = false; | ||
234 | bdc->delayed_status = false; | ||
235 | |||
236 | bdc_writel(bdc->regs, BDC_SPBBAL, bdc->scratchpad.sp_dma); | ||
237 | /* Init the SRR */ | ||
238 | temp = BDC_SRR_RWS | BDC_SRR_RST; | ||
239 | /* Reset the SRR */ | ||
240 | bdc_writel(bdc->regs, BDC_SRRINT(0), temp); | ||
241 | dev_dbg(bdc->dev, "bdc->srr.sr_bds =%p\n", bdc->srr.sr_bds); | ||
242 | temp = lower_32_bits(bdc->srr.dma_addr); | ||
243 | size = fls(NUM_SR_ENTRIES) - 2; | ||
244 | temp |= size; | ||
245 | dev_dbg(bdc->dev, "SRRBAL[0]=%08x NUM_SR_ENTRIES:%d size:%d\n", | ||
246 | temp, NUM_SR_ENTRIES, size); | ||
247 | |||
248 | low32 = lower_32_bits(temp); | ||
249 | upp32 = upper_32_bits(bdc->srr.dma_addr); | ||
250 | cpu_to_le32s(&low32); | ||
251 | cpu_to_le32s(&upp32); | ||
252 | |||
253 | /* Write the dma addresses into regs*/ | ||
254 | bdc_writel(bdc->regs, BDC_SRRBAL(0), low32); | ||
255 | bdc_writel(bdc->regs, BDC_SRRBAH(0), upp32); | ||
256 | |||
257 | temp = bdc_readl(bdc->regs, BDC_SRRINT(0)); | ||
258 | temp |= BDC_SRR_IE; | ||
259 | temp &= ~(BDC_SRR_RST | BDC_SRR_RWS); | ||
260 | bdc_writel(bdc->regs, BDC_SRRINT(0), temp); | ||
261 | |||
262 | /* Set the Interrupt Coalescence ~500 usec */ | ||
263 | temp = bdc_readl(bdc->regs, BDC_INTCTLS(0)); | ||
264 | temp &= ~0xffff; | ||
265 | temp |= INT_CLS; | ||
266 | bdc_writel(bdc->regs, BDC_INTCTLS(0), temp); | ||
267 | |||
268 | usb2_pm = bdc_readl(bdc->regs, BDC_USPPM2); | ||
269 | dev_dbg(bdc->dev, "usb2_pm=%08x", usb2_pm); | ||
270 | /* Enable hardware LPM Enable */ | ||
271 | usb2_pm |= BDC_HLE; | ||
272 | bdc_writel(bdc->regs, BDC_USPPM2, usb2_pm); | ||
273 | |||
274 | /* readback for debug */ | ||
275 | usb2_pm = bdc_readl(bdc->regs, BDC_USPPM2); | ||
276 | dev_dbg(bdc->dev, "usb2_pm=%08x\n", usb2_pm); | ||
277 | |||
278 | /* Disable any unwanted SR's on SRR */ | ||
279 | temp = bdc_readl(bdc->regs, BDC_BDCSC); | ||
280 | /* We don't want Microframe counter wrap SR */ | ||
281 | temp |= BDC_MASK_MCW; | ||
282 | bdc_writel(bdc->regs, BDC_BDCSC, temp); | ||
283 | |||
284 | /* | ||
285 | * In some error cases, driver has to reset the entire BDC controller | ||
286 | * in that case reinit is passed as 1 | ||
287 | */ | ||
288 | if (reinit) { | ||
289 | /* Enable interrupts */ | ||
290 | temp = bdc_readl(bdc->regs, BDC_BDCSC); | ||
291 | temp |= BDC_GIE; | ||
292 | bdc_writel(bdc->regs, BDC_BDCSC, temp); | ||
293 | /* Init scratchpad to 0 */ | ||
294 | memset(bdc->scratchpad.buff, 0, bdc->sp_buff_size); | ||
295 | /* Initialize SRR to 0 */ | ||
296 | memset(bdc->srr.sr_bds, 0, | ||
297 | NUM_SR_ENTRIES * sizeof(struct bdc_bd)); | ||
298 | } else { | ||
299 | /* One time initiaization only */ | ||
300 | /* Enable status report function pointers */ | ||
301 | bdc->sr_handler[0] = bdc_sr_xsf; | ||
302 | bdc->sr_handler[1] = bdc_sr_uspc; | ||
303 | |||
304 | /* EP0 status report function pointers */ | ||
305 | bdc->sr_xsf_ep0[0] = bdc_xsf_ep0_setup_recv; | ||
306 | bdc->sr_xsf_ep0[1] = bdc_xsf_ep0_data_start; | ||
307 | bdc->sr_xsf_ep0[2] = bdc_xsf_ep0_status_start; | ||
308 | } | ||
309 | } | ||
310 | |||
311 | /* Free the dynamic memory */ | ||
312 | static void bdc_mem_free(struct bdc *bdc) | ||
313 | { | ||
314 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
315 | /* Free SRR */ | ||
316 | if (bdc->srr.sr_bds) | ||
317 | dma_free_coherent(bdc->dev, | ||
318 | NUM_SR_ENTRIES * sizeof(struct bdc_bd), | ||
319 | bdc->srr.sr_bds, bdc->srr.dma_addr); | ||
320 | |||
321 | /* Free scratchpad */ | ||
322 | if (bdc->scratchpad.buff) | ||
323 | dma_free_coherent(bdc->dev, bdc->sp_buff_size, | ||
324 | bdc->scratchpad.buff, bdc->scratchpad.sp_dma); | ||
325 | |||
326 | /* Destroy the dma pools */ | ||
327 | if (bdc->bd_table_pool) | ||
328 | dma_pool_destroy(bdc->bd_table_pool); | ||
329 | |||
330 | /* Free the bdc_ep array */ | ||
331 | kfree(bdc->bdc_ep_array); | ||
332 | |||
333 | bdc->srr.sr_bds = NULL; | ||
334 | bdc->scratchpad.buff = NULL; | ||
335 | bdc->bd_table_pool = NULL; | ||
336 | bdc->bdc_ep_array = NULL; | ||
337 | } | ||
338 | |||
339 | /* | ||
340 | * bdc reinit gives a controller reset and reinitialize the registers, | ||
341 | * called from disconnect/bus reset scenario's, to ensure proper HW cleanup | ||
342 | */ | ||
343 | int bdc_reinit(struct bdc *bdc) | ||
344 | { | ||
345 | int ret; | ||
346 | |||
347 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
348 | ret = bdc_stop(bdc); | ||
349 | if (ret) | ||
350 | goto out; | ||
351 | |||
352 | ret = bdc_reset(bdc); | ||
353 | if (ret) | ||
354 | goto out; | ||
355 | |||
356 | /* the reinit flag is 1 */ | ||
357 | bdc_mem_init(bdc, true); | ||
358 | ret = bdc_run(bdc); | ||
359 | out: | ||
360 | bdc->reinit = false; | ||
361 | |||
362 | return ret; | ||
363 | } | ||
364 | |||
365 | /* Allocate all the dyanmic memory */ | ||
366 | static int bdc_mem_alloc(struct bdc *bdc) | ||
367 | { | ||
368 | u32 page_size; | ||
369 | unsigned int num_ieps, num_oeps; | ||
370 | |||
371 | dev_dbg(bdc->dev, | ||
372 | "%s() NUM_BDS_PER_TABLE:%d\n", __func__, | ||
373 | NUM_BDS_PER_TABLE); | ||
374 | page_size = BDC_PGS(bdc_readl(bdc->regs, BDC_BDCCFG0)); | ||
375 | /* page size is 2^pgs KB */ | ||
376 | page_size = 1 << page_size; | ||
377 | /* KB */ | ||
378 | page_size <<= 10; | ||
379 | dev_dbg(bdc->dev, "page_size=%d\n", page_size); | ||
380 | |||
381 | /* Create a pool of bd tables */ | ||
382 | bdc->bd_table_pool = | ||
383 | dma_pool_create("BDC BD tables", bdc->dev, NUM_BDS_PER_TABLE * 16, | ||
384 | 16, page_size); | ||
385 | |||
386 | if (!bdc->bd_table_pool) | ||
387 | goto fail; | ||
388 | |||
389 | if (scratchpad_setup(bdc)) | ||
390 | goto fail; | ||
391 | |||
392 | /* read from regs */ | ||
393 | num_ieps = NUM_NCS(bdc_readl(bdc->regs, BDC_FSCNIC)); | ||
394 | num_oeps = NUM_NCS(bdc_readl(bdc->regs, BDC_FSCNOC)); | ||
395 | /* +2: 1 for ep0 and the other is rsvd i.e. bdc_ep[0] is rsvd */ | ||
396 | bdc->num_eps = num_ieps + num_oeps + 2; | ||
397 | dev_dbg(bdc->dev, | ||
398 | "ieps:%d eops:%d num_eps:%d\n", | ||
399 | num_ieps, num_oeps, bdc->num_eps); | ||
400 | /* allocate array of ep pointers */ | ||
401 | bdc->bdc_ep_array = kcalloc(bdc->num_eps, sizeof(struct bdc_ep *), | ||
402 | GFP_KERNEL); | ||
403 | if (!bdc->bdc_ep_array) | ||
404 | goto fail; | ||
405 | |||
406 | dev_dbg(bdc->dev, "Allocating sr report0\n"); | ||
407 | if (setup_srr(bdc, 0)) | ||
408 | goto fail; | ||
409 | |||
410 | return 0; | ||
411 | fail: | ||
412 | dev_warn(bdc->dev, "Couldn't initialize memory\n"); | ||
413 | bdc_mem_free(bdc); | ||
414 | |||
415 | return -ENOMEM; | ||
416 | } | ||
417 | |||
418 | /* opposite to bdc_hw_init */ | ||
419 | static void bdc_hw_exit(struct bdc *bdc) | ||
420 | { | ||
421 | dev_dbg(bdc->dev, "%s ()\n", __func__); | ||
422 | bdc_mem_free(bdc); | ||
423 | } | ||
424 | |||
425 | /* Initialize the bdc HW and memory */ | ||
426 | static int bdc_hw_init(struct bdc *bdc) | ||
427 | { | ||
428 | int ret; | ||
429 | |||
430 | dev_dbg(bdc->dev, "%s ()\n", __func__); | ||
431 | ret = bdc_reset(bdc); | ||
432 | if (ret) { | ||
433 | dev_err(bdc->dev, "err resetting bdc abort bdc init%d\n", ret); | ||
434 | return ret; | ||
435 | } | ||
436 | ret = bdc_mem_alloc(bdc); | ||
437 | if (ret) { | ||
438 | dev_err(bdc->dev, "Mem alloc failed, aborting\n"); | ||
439 | return -ENOMEM; | ||
440 | } | ||
441 | bdc_mem_init(bdc, 0); | ||
442 | bdc_dbg_regs(bdc); | ||
443 | dev_dbg(bdc->dev, "HW Init done\n"); | ||
444 | |||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | static int bdc_probe(struct platform_device *pdev) | ||
449 | { | ||
450 | struct bdc *bdc; | ||
451 | struct resource *res; | ||
452 | int ret = -ENOMEM; | ||
453 | int irq; | ||
454 | u32 temp; | ||
455 | struct device *dev = &pdev->dev; | ||
456 | |||
457 | dev_dbg(dev, "%s()\n", __func__); | ||
458 | bdc = devm_kzalloc(dev, sizeof(*bdc), GFP_KERNEL); | ||
459 | if (!bdc) | ||
460 | return -ENOMEM; | ||
461 | |||
462 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
463 | bdc->regs = devm_ioremap_resource(dev, res); | ||
464 | if (IS_ERR(bdc->regs)) { | ||
465 | dev_err(dev, "ioremap error\n"); | ||
466 | return -ENOMEM; | ||
467 | } | ||
468 | irq = platform_get_irq(pdev, 0); | ||
469 | if (irq < 0) { | ||
470 | dev_err(dev, "platform_get_irq failed:%d\n", irq); | ||
471 | return irq; | ||
472 | } | ||
473 | spin_lock_init(&bdc->lock); | ||
474 | platform_set_drvdata(pdev, bdc); | ||
475 | bdc->irq = irq; | ||
476 | bdc->dev = dev; | ||
477 | dev_dbg(bdc->dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq); | ||
478 | |||
479 | temp = bdc_readl(bdc->regs, BDC_BDCSC); | ||
480 | if ((temp & BDC_P64) && | ||
481 | !dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) { | ||
482 | dev_dbg(bdc->dev, "Using 64-bit address\n"); | ||
483 | } else { | ||
484 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); | ||
485 | if (ret) { | ||
486 | dev_err(bdc->dev, "No suitable DMA config available, abort\n"); | ||
487 | return -ENOTSUPP; | ||
488 | } | ||
489 | dev_dbg(bdc->dev, "Using 32-bit address\n"); | ||
490 | } | ||
491 | ret = bdc_hw_init(bdc); | ||
492 | if (ret) { | ||
493 | dev_err(bdc->dev, "BDC init failure:%d\n", ret); | ||
494 | return ret; | ||
495 | } | ||
496 | ret = bdc_udc_init(bdc); | ||
497 | if (ret) { | ||
498 | dev_err(bdc->dev, "BDC Gadget init failure:%d\n", ret); | ||
499 | goto cleanup; | ||
500 | } | ||
501 | return 0; | ||
502 | |||
503 | cleanup: | ||
504 | bdc_hw_exit(bdc); | ||
505 | |||
506 | return ret; | ||
507 | } | ||
508 | |||
509 | static int bdc_remove(struct platform_device *pdev) | ||
510 | { | ||
511 | struct bdc *bdc; | ||
512 | |||
513 | bdc = platform_get_drvdata(pdev); | ||
514 | dev_dbg(bdc->dev, "%s ()\n", __func__); | ||
515 | bdc_udc_exit(bdc); | ||
516 | bdc_hw_exit(bdc); | ||
517 | |||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | static struct platform_driver bdc_driver = { | ||
522 | .driver = { | ||
523 | .name = BRCM_BDC_NAME, | ||
524 | .owner = THIS_MODULE | ||
525 | }, | ||
526 | .probe = bdc_probe, | ||
527 | .remove = bdc_remove, | ||
528 | }; | ||
529 | |||
530 | module_platform_driver(bdc_driver); | ||
531 | MODULE_AUTHOR("Ashwini Pahuja <ashwini.linux@gmail.com>"); | ||
532 | MODULE_LICENSE("GPL"); | ||
533 | MODULE_DESCRIPTION(BRCM_BDC_DESC); | ||
diff --git a/drivers/usb/gadget/udc/bdc/bdc_dbg.c b/drivers/usb/gadget/udc/bdc/bdc_dbg.c new file mode 100644 index 000000000000..5945dbc47825 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_dbg.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * bdc_dbg.c - BRCM BDC USB3.0 device controller debug functions | ||
3 | * | ||
4 | * Copyright (C) 2014 Broadcom Corporation | ||
5 | * | ||
6 | * Author: Ashwini Pahuja | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include "bdc.h" | ||
16 | #include "bdc_dbg.h" | ||
17 | |||
18 | void bdc_dbg_regs(struct bdc *bdc) | ||
19 | { | ||
20 | u32 temp; | ||
21 | |||
22 | dev_vdbg(bdc->dev, "bdc->regs:%p\n", bdc->regs); | ||
23 | temp = bdc_readl(bdc->regs, BDC_BDCCFG0); | ||
24 | dev_vdbg(bdc->dev, "bdccfg0:0x%08x\n", temp); | ||
25 | temp = bdc_readl(bdc->regs, BDC_BDCCFG1); | ||
26 | dev_vdbg(bdc->dev, "bdccfg1:0x%08x\n", temp); | ||
27 | temp = bdc_readl(bdc->regs, BDC_BDCCAP0); | ||
28 | dev_vdbg(bdc->dev, "bdccap0:0x%08x\n", temp); | ||
29 | temp = bdc_readl(bdc->regs, BDC_BDCCAP1); | ||
30 | dev_vdbg(bdc->dev, "bdccap1:0x%08x\n", temp); | ||
31 | temp = bdc_readl(bdc->regs, BDC_USPC); | ||
32 | dev_vdbg(bdc->dev, "uspc:0x%08x\n", temp); | ||
33 | temp = bdc_readl(bdc->regs, BDC_DVCSA); | ||
34 | dev_vdbg(bdc->dev, "dvcsa:0x%08x\n", temp); | ||
35 | temp = bdc_readl(bdc->regs, BDC_DVCSB); | ||
36 | dev_vdbg(bdc->dev, "dvcsb:0x%x08\n", temp); | ||
37 | } | ||
38 | |||
39 | void bdc_dump_epsts(struct bdc *bdc) | ||
40 | { | ||
41 | u32 temp; | ||
42 | |||
43 | temp = bdc_readl(bdc->regs, BDC_EPSTS0(0)); | ||
44 | dev_vdbg(bdc->dev, "BDC_EPSTS0:0x%08x\n", temp); | ||
45 | |||
46 | temp = bdc_readl(bdc->regs, BDC_EPSTS1(0)); | ||
47 | dev_vdbg(bdc->dev, "BDC_EPSTS1:0x%x\n", temp); | ||
48 | |||
49 | temp = bdc_readl(bdc->regs, BDC_EPSTS2(0)); | ||
50 | dev_vdbg(bdc->dev, "BDC_EPSTS2:0x%08x\n", temp); | ||
51 | |||
52 | temp = bdc_readl(bdc->regs, BDC_EPSTS3(0)); | ||
53 | dev_vdbg(bdc->dev, "BDC_EPSTS3:0x%08x\n", temp); | ||
54 | |||
55 | temp = bdc_readl(bdc->regs, BDC_EPSTS4(0)); | ||
56 | dev_vdbg(bdc->dev, "BDC_EPSTS4:0x%08x\n", temp); | ||
57 | |||
58 | temp = bdc_readl(bdc->regs, BDC_EPSTS5(0)); | ||
59 | dev_vdbg(bdc->dev, "BDC_EPSTS5:0x%08x\n", temp); | ||
60 | |||
61 | temp = bdc_readl(bdc->regs, BDC_EPSTS6(0)); | ||
62 | dev_vdbg(bdc->dev, "BDC_EPSTS6:0x%08x\n", temp); | ||
63 | |||
64 | temp = bdc_readl(bdc->regs, BDC_EPSTS7(0)); | ||
65 | dev_vdbg(bdc->dev, "BDC_EPSTS7:0x%08x\n", temp); | ||
66 | } | ||
67 | |||
68 | void bdc_dbg_srr(struct bdc *bdc, u32 srr_num) | ||
69 | { | ||
70 | struct bdc_sr *sr; | ||
71 | dma_addr_t addr; | ||
72 | int i; | ||
73 | |||
74 | sr = bdc->srr.sr_bds; | ||
75 | addr = bdc->srr.dma_addr; | ||
76 | dev_vdbg(bdc->dev, "bdc_dbg_srr sr:%p dqp_index:%d\n", | ||
77 | sr, bdc->srr.dqp_index); | ||
78 | for (i = 0; i < NUM_SR_ENTRIES; i++) { | ||
79 | sr = &bdc->srr.sr_bds[i]; | ||
80 | dev_vdbg(bdc->dev, "%llx %08x %08x %08x %08x\n", | ||
81 | (unsigned long long)addr, | ||
82 | le32_to_cpu(sr->offset[0]), | ||
83 | le32_to_cpu(sr->offset[1]), | ||
84 | le32_to_cpu(sr->offset[2]), | ||
85 | le32_to_cpu(sr->offset[3])); | ||
86 | addr += sizeof(*sr); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | void bdc_dbg_bd_list(struct bdc *bdc, struct bdc_ep *ep) | ||
91 | { | ||
92 | struct bd_list *bd_list = &ep->bd_list; | ||
93 | struct bd_table *bd_table; | ||
94 | struct bdc_bd *bd; | ||
95 | int tbi, bdi, gbdi; | ||
96 | dma_addr_t dma; | ||
97 | |||
98 | gbdi = 0; | ||
99 | dev_vdbg(bdc->dev, | ||
100 | "Dump bd list for %s epnum:%d\n", | ||
101 | ep->name, ep->ep_num); | ||
102 | |||
103 | dev_vdbg(bdc->dev, | ||
104 | "tabs:%d max_bdi:%d eqp_bdi:%d hwd_bdi:%d num_bds_table:%d\n", | ||
105 | bd_list->num_tabs, bd_list->max_bdi, bd_list->eqp_bdi, | ||
106 | bd_list->hwd_bdi, bd_list->num_bds_table); | ||
107 | |||
108 | for (tbi = 0; tbi < bd_list->num_tabs; tbi++) { | ||
109 | bd_table = bd_list->bd_table_array[tbi]; | ||
110 | for (bdi = 0; bdi < bd_list->num_bds_table; bdi++) { | ||
111 | bd = bd_table->start_bd + bdi; | ||
112 | dma = bd_table->dma + (sizeof(struct bdc_bd) * bdi); | ||
113 | dev_vdbg(bdc->dev, | ||
114 | "tbi:%2d bdi:%2d gbdi:%2d virt:%p phys:%llx %08x %08x %08x %08x\n", | ||
115 | tbi, bdi, gbdi++, bd, (unsigned long long)dma, | ||
116 | le32_to_cpu(bd->offset[0]), | ||
117 | le32_to_cpu(bd->offset[1]), | ||
118 | le32_to_cpu(bd->offset[2]), | ||
119 | le32_to_cpu(bd->offset[3])); | ||
120 | } | ||
121 | dev_vdbg(bdc->dev, "\n\n"); | ||
122 | } | ||
123 | } | ||
diff --git a/drivers/usb/gadget/udc/bdc/bdc_dbg.h b/drivers/usb/gadget/udc/bdc/bdc_dbg.h new file mode 100644 index 000000000000..338a6c701315 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_dbg.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * bdc_dbg.h - header for the BDC debug functions | ||
3 | * | ||
4 | * Copyright (C) 2014 Broadcom Corporation | ||
5 | * | ||
6 | * Author: Ashwini Pahuja | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | #ifndef __LINUX_BDC_DBG_H__ | ||
15 | #define __LINUX_BDC_DBG_H__ | ||
16 | |||
17 | #include "bdc.h" | ||
18 | |||
19 | #ifdef CONFIG_USB_GADGET_VERBOSE | ||
20 | void bdc_dbg_bd_list(struct bdc *, struct bdc_ep*); | ||
21 | void bdc_dbg_srr(struct bdc *, u32); | ||
22 | void bdc_dbg_regs(struct bdc *); | ||
23 | void bdc_dump_epsts(struct bdc *); | ||
24 | #else | ||
25 | static inline void bdc_dbg_regs(struct bdc *bdc) | ||
26 | { } | ||
27 | |||
28 | static inline void bdc_dbg_srr(struct bdc *bdc, u32 srr_num) | ||
29 | { } | ||
30 | |||
31 | static inline void bdc_dbg_bd_list(struct bdc *bdc, struct bdc_ep *ep) | ||
32 | { } | ||
33 | |||
34 | static inline void bdc_dump_epsts(struct bdc *bdc) | ||
35 | { } | ||
36 | #endif /* CONFIG_USB_GADGET_VERBOSE */ | ||
37 | #endif /* __LINUX_BDC_DBG_H__ */ | ||
diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c new file mode 100644 index 000000000000..15da5b1e76c0 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c | |||
@@ -0,0 +1,2023 @@ | |||
1 | /* | ||
2 | * bdc_ep.c - BRCM BDC USB3.0 device controller endpoint related functions | ||
3 | * | ||
4 | * Copyright (C) 2014 Broadcom Corporation | ||
5 | * | ||
6 | * Author: Ashwini Pahuja | ||
7 | * | ||
8 | * Based on drivers under drivers/usb/ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/pci.h> | ||
18 | #include <linux/dma-mapping.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/dmapool.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/timer.h> | ||
28 | #include <linux/list.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/moduleparam.h> | ||
31 | #include <linux/device.h> | ||
32 | #include <linux/usb/ch9.h> | ||
33 | #include <linux/usb/gadget.h> | ||
34 | #include <linux/usb/otg.h> | ||
35 | #include <linux/pm.h> | ||
36 | #include <linux/io.h> | ||
37 | #include <linux/irq.h> | ||
38 | #include <asm/unaligned.h> | ||
39 | #include <linux/platform_device.h> | ||
40 | #include <linux/usb/composite.h> | ||
41 | |||
42 | #include "bdc.h" | ||
43 | #include "bdc_ep.h" | ||
44 | #include "bdc_cmd.h" | ||
45 | #include "bdc_dbg.h" | ||
46 | |||
47 | static const char * const ep0_state_string[] = { | ||
48 | "WAIT_FOR_SETUP", | ||
49 | "WAIT_FOR_DATA_START", | ||
50 | "WAIT_FOR_DATA_XMIT", | ||
51 | "WAIT_FOR_STATUS_START", | ||
52 | "WAIT_FOR_STATUS_XMIT", | ||
53 | "STATUS_PENDING" | ||
54 | }; | ||
55 | |||
56 | /* Free the bdl during ep disable */ | ||
57 | static void ep_bd_list_free(struct bdc_ep *ep, u32 num_tabs) | ||
58 | { | ||
59 | struct bd_list *bd_list = &ep->bd_list; | ||
60 | struct bdc *bdc = ep->bdc; | ||
61 | struct bd_table *bd_table; | ||
62 | int index; | ||
63 | |||
64 | dev_dbg(bdc->dev, "%s ep:%s num_tabs:%d\n", | ||
65 | __func__, ep->name, num_tabs); | ||
66 | |||
67 | if (!bd_list->bd_table_array) { | ||
68 | dev_dbg(bdc->dev, "%s already freed\n", ep->name); | ||
69 | return; | ||
70 | } | ||
71 | for (index = 0; index < num_tabs; index++) { | ||
72 | /* | ||
73 | * check if the bd_table struct is allocated ? | ||
74 | * if yes, then check if bd memory has been allocated, then | ||
75 | * free the dma_pool and also the bd_table struct memory | ||
76 | */ | ||
77 | bd_table = bd_list->bd_table_array[index]; | ||
78 | dev_dbg(bdc->dev, "bd_table:%p index:%d\n", bd_table, index); | ||
79 | if (!bd_table) { | ||
80 | dev_dbg(bdc->dev, "bd_table not allocated\n"); | ||
81 | continue; | ||
82 | } | ||
83 | if (!bd_table->start_bd) { | ||
84 | dev_dbg(bdc->dev, "bd dma pool not allocted\n"); | ||
85 | continue; | ||
86 | } | ||
87 | |||
88 | dev_dbg(bdc->dev, | ||
89 | "Free dma pool start_bd:%p dma:%llx\n", | ||
90 | bd_table->start_bd, | ||
91 | (unsigned long long)bd_table->dma); | ||
92 | |||
93 | dma_pool_free(bdc->bd_table_pool, | ||
94 | bd_table->start_bd, | ||
95 | bd_table->dma); | ||
96 | /* Free the bd_table structure */ | ||
97 | kfree(bd_table); | ||
98 | } | ||
99 | /* Free the bd table array */ | ||
100 | kfree(ep->bd_list.bd_table_array); | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * chain the tables, by insteting a chain bd at the end of prev_table, pointing | ||
105 | * to next_table | ||
106 | */ | ||
107 | static inline void chain_table(struct bd_table *prev_table, | ||
108 | struct bd_table *next_table, | ||
109 | u32 bd_p_tab) | ||
110 | { | ||
111 | /* Chain the prev table to next table */ | ||
112 | prev_table->start_bd[bd_p_tab-1].offset[0] = | ||
113 | cpu_to_le32(lower_32_bits(next_table->dma)); | ||
114 | |||
115 | prev_table->start_bd[bd_p_tab-1].offset[1] = | ||
116 | cpu_to_le32(upper_32_bits(next_table->dma)); | ||
117 | |||
118 | prev_table->start_bd[bd_p_tab-1].offset[2] = | ||
119 | 0x0; | ||
120 | |||
121 | prev_table->start_bd[bd_p_tab-1].offset[3] = | ||
122 | cpu_to_le32(MARK_CHAIN_BD); | ||
123 | } | ||
124 | |||
125 | /* Allocate the bdl for ep, during config ep */ | ||
126 | static int ep_bd_list_alloc(struct bdc_ep *ep) | ||
127 | { | ||
128 | struct bd_table *prev_table = NULL; | ||
129 | int index, num_tabs, bd_p_tab; | ||
130 | struct bdc *bdc = ep->bdc; | ||
131 | struct bd_table *bd_table; | ||
132 | dma_addr_t dma; | ||
133 | |||
134 | if (usb_endpoint_xfer_isoc(ep->desc)) | ||
135 | num_tabs = NUM_TABLES_ISOCH; | ||
136 | else | ||
137 | num_tabs = NUM_TABLES; | ||
138 | |||
139 | bd_p_tab = NUM_BDS_PER_TABLE; | ||
140 | /* if there is only 1 table in bd list then loop chain to self */ | ||
141 | dev_dbg(bdc->dev, | ||
142 | "%s ep:%p num_tabs:%d\n", | ||
143 | __func__, ep, num_tabs); | ||
144 | |||
145 | /* Allocate memory for table array */ | ||
146 | ep->bd_list.bd_table_array = kzalloc( | ||
147 | num_tabs * sizeof(struct bd_table *), | ||
148 | GFP_ATOMIC); | ||
149 | if (!ep->bd_list.bd_table_array) | ||
150 | return -ENOMEM; | ||
151 | |||
152 | /* Allocate memory for each table */ | ||
153 | for (index = 0; index < num_tabs; index++) { | ||
154 | /* Allocate memory for bd_table structure */ | ||
155 | bd_table = kzalloc(sizeof(struct bd_table), GFP_ATOMIC); | ||
156 | if (!bd_table) | ||
157 | goto fail; | ||
158 | |||
159 | bd_table->start_bd = dma_pool_alloc(bdc->bd_table_pool, | ||
160 | GFP_ATOMIC, | ||
161 | &dma); | ||
162 | if (!bd_table->start_bd) | ||
163 | goto fail; | ||
164 | |||
165 | bd_table->dma = dma; | ||
166 | |||
167 | dev_dbg(bdc->dev, | ||
168 | "index:%d start_bd:%p dma=%08llx prev_table:%p\n", | ||
169 | index, bd_table->start_bd, | ||
170 | (unsigned long long)bd_table->dma, prev_table); | ||
171 | |||
172 | ep->bd_list.bd_table_array[index] = bd_table; | ||
173 | memset(bd_table->start_bd, 0, bd_p_tab * sizeof(struct bdc_bd)); | ||
174 | if (prev_table) | ||
175 | chain_table(prev_table, bd_table, bd_p_tab); | ||
176 | |||
177 | prev_table = bd_table; | ||
178 | } | ||
179 | chain_table(prev_table, ep->bd_list.bd_table_array[0], bd_p_tab); | ||
180 | /* Memory allocation is successful, now init the internal fields */ | ||
181 | ep->bd_list.num_tabs = num_tabs; | ||
182 | ep->bd_list.max_bdi = (num_tabs * bd_p_tab) - 1; | ||
183 | ep->bd_list.num_tabs = num_tabs; | ||
184 | ep->bd_list.num_bds_table = bd_p_tab; | ||
185 | ep->bd_list.eqp_bdi = 0; | ||
186 | ep->bd_list.hwd_bdi = 0; | ||
187 | |||
188 | return 0; | ||
189 | fail: | ||
190 | /* Free the bd_table_array, bd_table struct, bd's */ | ||
191 | ep_bd_list_free(ep, num_tabs); | ||
192 | |||
193 | return -ENOMEM; | ||
194 | } | ||
195 | |||
196 | /* returns how many bd's are need for this transfer */ | ||
197 | static inline int bd_needed_req(struct bdc_req *req) | ||
198 | { | ||
199 | int bd_needed = 0; | ||
200 | int remaining; | ||
201 | |||
202 | /* 1 bd needed for 0 byte transfer */ | ||
203 | if (req->usb_req.length == 0) | ||
204 | return 1; | ||
205 | |||
206 | /* remaining bytes after tranfering all max BD size BD's */ | ||
207 | remaining = req->usb_req.length % BD_MAX_BUFF_SIZE; | ||
208 | if (remaining) | ||
209 | bd_needed++; | ||
210 | |||
211 | /* How many maximum BUFF size BD's ? */ | ||
212 | remaining = req->usb_req.length / BD_MAX_BUFF_SIZE; | ||
213 | bd_needed += remaining; | ||
214 | |||
215 | return bd_needed; | ||
216 | } | ||
217 | |||
218 | /* returns the bd index(bdi) corresponding to bd dma address */ | ||
219 | static int bd_add_to_bdi(struct bdc_ep *ep, dma_addr_t bd_dma_addr) | ||
220 | { | ||
221 | struct bd_list *bd_list = &ep->bd_list; | ||
222 | dma_addr_t dma_first_bd, dma_last_bd; | ||
223 | struct bdc *bdc = ep->bdc; | ||
224 | struct bd_table *bd_table; | ||
225 | bool found = false; | ||
226 | int tbi, bdi; | ||
227 | |||
228 | dma_first_bd = dma_last_bd = 0; | ||
229 | dev_dbg(bdc->dev, "%s %llx\n", | ||
230 | __func__, (unsigned long long)bd_dma_addr); | ||
231 | /* | ||
232 | * Find in which table this bd_dma_addr belongs?, go through the table | ||
233 | * array and compare addresses of first and last address of bd of each | ||
234 | * table | ||
235 | */ | ||
236 | for (tbi = 0; tbi < bd_list->num_tabs; tbi++) { | ||
237 | bd_table = bd_list->bd_table_array[tbi]; | ||
238 | dma_first_bd = bd_table->dma; | ||
239 | dma_last_bd = bd_table->dma + | ||
240 | (sizeof(struct bdc_bd) * | ||
241 | (bd_list->num_bds_table - 1)); | ||
242 | dev_dbg(bdc->dev, "dma_first_bd:%llx dma_last_bd:%llx\n", | ||
243 | (unsigned long long)dma_first_bd, | ||
244 | (unsigned long long)dma_last_bd); | ||
245 | if (bd_dma_addr >= dma_first_bd && bd_dma_addr <= dma_last_bd) { | ||
246 | found = true; | ||
247 | break; | ||
248 | } | ||
249 | } | ||
250 | if (unlikely(!found)) { | ||
251 | dev_err(bdc->dev, "%s FATAL err, bd not found\n", __func__); | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | /* Now we know the table, find the bdi */ | ||
255 | bdi = (bd_dma_addr - dma_first_bd) / sizeof(struct bdc_bd); | ||
256 | |||
257 | /* return the global bdi, to compare with ep eqp_bdi */ | ||
258 | return (bdi + (tbi * bd_list->num_bds_table)); | ||
259 | } | ||
260 | |||
261 | /* returns the table index(tbi) of the given bdi */ | ||
262 | static int bdi_to_tbi(struct bdc_ep *ep, int bdi) | ||
263 | { | ||
264 | int tbi; | ||
265 | |||
266 | tbi = bdi / ep->bd_list.num_bds_table; | ||
267 | dev_vdbg(ep->bdc->dev, | ||
268 | "bdi:%d num_bds_table:%d tbi:%d\n", | ||
269 | bdi, ep->bd_list.num_bds_table, tbi); | ||
270 | |||
271 | return tbi; | ||
272 | } | ||
273 | |||
274 | /* Find the bdi last bd in the transfer */ | ||
275 | static inline int find_end_bdi(struct bdc_ep *ep, int next_hwd_bdi) | ||
276 | { | ||
277 | int end_bdi; | ||
278 | |||
279 | end_bdi = next_hwd_bdi - 1; | ||
280 | if (end_bdi < 0) | ||
281 | end_bdi = ep->bd_list.max_bdi - 1; | ||
282 | else if ((end_bdi % (ep->bd_list.num_bds_table-1)) == 0) | ||
283 | end_bdi--; | ||
284 | |||
285 | return end_bdi; | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * How many transfer bd's are available on this ep bdl, chain bds are not | ||
290 | * counted in available bds | ||
291 | */ | ||
292 | static int bd_available_ep(struct bdc_ep *ep) | ||
293 | { | ||
294 | struct bd_list *bd_list = &ep->bd_list; | ||
295 | int available1, available2; | ||
296 | struct bdc *bdc = ep->bdc; | ||
297 | int chain_bd1, chain_bd2; | ||
298 | int available_bd = 0; | ||
299 | |||
300 | available1 = available2 = chain_bd1 = chain_bd2 = 0; | ||
301 | /* if empty then we have all bd's available - number of chain bd's */ | ||
302 | if (bd_list->eqp_bdi == bd_list->hwd_bdi) | ||
303 | return bd_list->max_bdi - bd_list->num_tabs; | ||
304 | |||
305 | /* | ||
306 | * Depending upon where eqp and dqp pointers are, caculate number | ||
307 | * of avaialble bd's | ||
308 | */ | ||
309 | if (bd_list->hwd_bdi < bd_list->eqp_bdi) { | ||
310 | /* available bd's are from eqp..max_bds + 0..dqp - chain_bds */ | ||
311 | available1 = bd_list->max_bdi - bd_list->eqp_bdi; | ||
312 | available2 = bd_list->hwd_bdi; | ||
313 | chain_bd1 = available1 / bd_list->num_bds_table; | ||
314 | chain_bd2 = available2 / bd_list->num_bds_table; | ||
315 | dev_vdbg(bdc->dev, "chain_bd1:%d chain_bd2:%d\n", | ||
316 | chain_bd1, chain_bd2); | ||
317 | available_bd = available1 + available2 - chain_bd1 - chain_bd2; | ||
318 | } else { | ||
319 | /* available bd's are from eqp..dqp - number of chain bd's */ | ||
320 | available1 = bd_list->hwd_bdi - bd_list->eqp_bdi; | ||
321 | /* if gap between eqp and dqp is less than NUM_BDS_PER_TABLE */ | ||
322 | if ((bd_list->hwd_bdi - bd_list->eqp_bdi) | ||
323 | <= bd_list->num_bds_table) { | ||
324 | /* If there any chain bd in between */ | ||
325 | if (!(bdi_to_tbi(ep, bd_list->hwd_bdi) | ||
326 | == bdi_to_tbi(ep, bd_list->eqp_bdi))) { | ||
327 | available_bd = available1 - 1; | ||
328 | } | ||
329 | } else { | ||
330 | chain_bd1 = available1 / bd_list->num_bds_table; | ||
331 | available_bd = available1 - chain_bd1; | ||
332 | } | ||
333 | } | ||
334 | /* | ||
335 | * we need to keep one extra bd to check if ring is full or empty so | ||
336 | * reduce by 1 | ||
337 | */ | ||
338 | available_bd--; | ||
339 | dev_vdbg(bdc->dev, "available_bd:%d\n", available_bd); | ||
340 | |||
341 | return available_bd; | ||
342 | } | ||
343 | |||
344 | /* Notify the hardware after queueing the bd to bdl */ | ||
345 | void bdc_notify_xfr(struct bdc *bdc, u32 epnum) | ||
346 | { | ||
347 | struct bdc_ep *ep = bdc->bdc_ep_array[epnum]; | ||
348 | |||
349 | dev_vdbg(bdc->dev, "%s epnum:%d\n", __func__, epnum); | ||
350 | /* | ||
351 | * We don't have anyway to check if ep state is running, | ||
352 | * except the software flags. | ||
353 | */ | ||
354 | if (unlikely(ep->flags & BDC_EP_STOP)) | ||
355 | ep->flags &= ~BDC_EP_STOP; | ||
356 | |||
357 | bdc_writel(bdc->regs, BDC_XSFNTF, epnum); | ||
358 | } | ||
359 | |||
360 | /* returns the bd corresponding to bdi */ | ||
361 | static struct bdc_bd *bdi_to_bd(struct bdc_ep *ep, int bdi) | ||
362 | { | ||
363 | int tbi = bdi_to_tbi(ep, bdi); | ||
364 | int local_bdi = 0; | ||
365 | |||
366 | local_bdi = bdi - (tbi * ep->bd_list.num_bds_table); | ||
367 | dev_vdbg(ep->bdc->dev, | ||
368 | "%s bdi:%d local_bdi:%d\n", | ||
369 | __func__, bdi, local_bdi); | ||
370 | |||
371 | return (ep->bd_list.bd_table_array[tbi]->start_bd + local_bdi); | ||
372 | } | ||
373 | |||
374 | /* Advance the enqueue pointer */ | ||
375 | static void ep_bdlist_eqp_adv(struct bdc_ep *ep) | ||
376 | { | ||
377 | ep->bd_list.eqp_bdi++; | ||
378 | /* if it's chain bd, then move to next */ | ||
379 | if (((ep->bd_list.eqp_bdi + 1) % ep->bd_list.num_bds_table) == 0) | ||
380 | ep->bd_list.eqp_bdi++; | ||
381 | |||
382 | /* if the eqp is pointing to last + 1 then move back to 0 */ | ||
383 | if (ep->bd_list.eqp_bdi == (ep->bd_list.max_bdi + 1)) | ||
384 | ep->bd_list.eqp_bdi = 0; | ||
385 | } | ||
386 | |||
387 | /* Setup the first bd for ep0 transfer */ | ||
388 | static int setup_first_bd_ep0(struct bdc *bdc, struct bdc_req *req, u32 *dword3) | ||
389 | { | ||
390 | u16 wValue; | ||
391 | u32 req_len; | ||
392 | |||
393 | req->ep->dir = 0; | ||
394 | req_len = req->usb_req.length; | ||
395 | switch (bdc->ep0_state) { | ||
396 | case WAIT_FOR_DATA_START: | ||
397 | *dword3 |= BD_TYPE_DS; | ||
398 | if (bdc->setup_pkt.bRequestType & USB_DIR_IN) | ||
399 | *dword3 |= BD_DIR_IN; | ||
400 | |||
401 | /* check if zlp will be needed */ | ||
402 | wValue = le16_to_cpu(bdc->setup_pkt.wValue); | ||
403 | if ((wValue > req_len) && | ||
404 | (req_len % bdc->gadget.ep0->maxpacket == 0)) { | ||
405 | dev_dbg(bdc->dev, "ZLP needed wVal:%d len:%d MaxP:%d\n", | ||
406 | wValue, req_len, | ||
407 | bdc->gadget.ep0->maxpacket); | ||
408 | bdc->zlp_needed = true; | ||
409 | } | ||
410 | break; | ||
411 | |||
412 | case WAIT_FOR_STATUS_START: | ||
413 | *dword3 |= BD_TYPE_SS; | ||
414 | if (!le16_to_cpu(bdc->setup_pkt.wLength) || | ||
415 | !(bdc->setup_pkt.bRequestType & USB_DIR_IN)) | ||
416 | *dword3 |= BD_DIR_IN; | ||
417 | break; | ||
418 | default: | ||
419 | dev_err(bdc->dev, | ||
420 | "Unknown ep0 state for queueing bd ep0_state:%s\n", | ||
421 | ep0_state_string[bdc->ep0_state]); | ||
422 | return -EINVAL; | ||
423 | } | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | /* Setup the bd dma descriptor for a given request */ | ||
429 | static int setup_bd_list_xfr(struct bdc *bdc, struct bdc_req *req, int num_bds) | ||
430 | { | ||
431 | dma_addr_t buf_add = req->usb_req.dma; | ||
432 | u32 maxp, tfs, dword2, dword3; | ||
433 | struct bd_transfer *bd_xfr; | ||
434 | struct bd_list *bd_list; | ||
435 | struct bdc_ep *ep; | ||
436 | struct bdc_bd *bd; | ||
437 | int ret, bdnum; | ||
438 | u32 req_len; | ||
439 | |||
440 | ep = req->ep; | ||
441 | bd_list = &ep->bd_list; | ||
442 | bd_xfr = &req->bd_xfr; | ||
443 | bd_xfr->req = req; | ||
444 | bd_xfr->start_bdi = bd_list->eqp_bdi; | ||
445 | bd = bdi_to_bd(ep, bd_list->eqp_bdi); | ||
446 | req_len = req->usb_req.length; | ||
447 | maxp = usb_endpoint_maxp(ep->desc) & 0x7ff; | ||
448 | tfs = roundup(req->usb_req.length, maxp); | ||
449 | tfs = tfs/maxp; | ||
450 | dev_vdbg(bdc->dev, "%s ep:%s num_bds:%d tfs:%d r_len:%d bd:%p\n", | ||
451 | __func__, ep->name, num_bds, tfs, req_len, bd); | ||
452 | |||
453 | for (bdnum = 0; bdnum < num_bds; bdnum++) { | ||
454 | dword2 = dword3 = 0; | ||
455 | /* First bd */ | ||
456 | if (!bdnum) { | ||
457 | dword3 |= BD_SOT|BD_SBF|(tfs<<BD_TFS_SHIFT); | ||
458 | dword2 |= BD_LTF; | ||
459 | /* format of first bd for ep0 is different than other */ | ||
460 | if (ep->ep_num == 1) | ||
461 | ret = setup_first_bd_ep0(bdc, req, &dword3); | ||
462 | if (ret) | ||
463 | return ret; | ||
464 | } | ||
465 | if (!req->ep->dir) | ||
466 | dword3 |= BD_ISP; | ||
467 | |||
468 | if (req_len > BD_MAX_BUFF_SIZE) { | ||
469 | dword2 |= BD_MAX_BUFF_SIZE; | ||
470 | req_len -= BD_MAX_BUFF_SIZE; | ||
471 | } else { | ||
472 | /* this should be the last bd */ | ||
473 | dword2 |= req_len; | ||
474 | dword3 |= BD_IOC; | ||
475 | dword3 |= BD_EOT; | ||
476 | } | ||
477 | /* Currently only 1 INT target is supported */ | ||
478 | dword2 |= BD_INTR_TARGET(0); | ||
479 | bd = bdi_to_bd(ep, ep->bd_list.eqp_bdi); | ||
480 | if (unlikely(!bd)) { | ||
481 | dev_err(bdc->dev, "Err bd pointing to wrong addr\n"); | ||
482 | return -EINVAL; | ||
483 | } | ||
484 | /* write bd */ | ||
485 | bd->offset[0] = cpu_to_le32(lower_32_bits(buf_add)); | ||
486 | bd->offset[1] = cpu_to_le32(upper_32_bits(buf_add)); | ||
487 | bd->offset[2] = cpu_to_le32(dword2); | ||
488 | bd->offset[3] = cpu_to_le32(dword3); | ||
489 | /* advance eqp pointer */ | ||
490 | ep_bdlist_eqp_adv(ep); | ||
491 | /* advance the buff pointer */ | ||
492 | buf_add += BD_MAX_BUFF_SIZE; | ||
493 | dev_vdbg(bdc->dev, "buf_add:%08llx req_len:%d bd:%p eqp:%d\n", | ||
494 | (unsigned long long)buf_add, req_len, bd, | ||
495 | ep->bd_list.eqp_bdi); | ||
496 | bd = bdi_to_bd(ep, ep->bd_list.eqp_bdi); | ||
497 | bd->offset[3] = cpu_to_le32(BD_SBF); | ||
498 | } | ||
499 | /* clear the STOP BD fetch bit from the first bd of this xfr */ | ||
500 | bd = bdi_to_bd(ep, bd_xfr->start_bdi); | ||
501 | bd->offset[3] &= cpu_to_le32(~BD_SBF); | ||
502 | /* the new eqp will be next hw dqp */ | ||
503 | bd_xfr->num_bds = num_bds; | ||
504 | bd_xfr->next_hwd_bdi = ep->bd_list.eqp_bdi; | ||
505 | /* everything is written correctly before notifying the HW */ | ||
506 | wmb(); | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | /* Queue the xfr */ | ||
512 | static int bdc_queue_xfr(struct bdc *bdc, struct bdc_req *req) | ||
513 | { | ||
514 | int num_bds, bd_available; | ||
515 | struct bdc_ep *ep; | ||
516 | int ret; | ||
517 | |||
518 | ep = req->ep; | ||
519 | dev_dbg(bdc->dev, "%s req:%p\n", __func__, req); | ||
520 | dev_dbg(bdc->dev, "eqp_bdi:%d hwd_bdi:%d\n", | ||
521 | ep->bd_list.eqp_bdi, ep->bd_list.hwd_bdi); | ||
522 | |||
523 | num_bds = bd_needed_req(req); | ||
524 | bd_available = bd_available_ep(ep); | ||
525 | |||
526 | /* how many bd's are avaialble on ep */ | ||
527 | if (num_bds > bd_available) | ||
528 | return -ENOMEM; | ||
529 | |||
530 | ret = setup_bd_list_xfr(bdc, req, num_bds); | ||
531 | if (ret) | ||
532 | return ret; | ||
533 | list_add_tail(&req->queue, &ep->queue); | ||
534 | bdc_dbg_bd_list(bdc, ep); | ||
535 | bdc_notify_xfr(bdc, ep->ep_num); | ||
536 | |||
537 | return 0; | ||
538 | } | ||
539 | |||
540 | /* callback to gadget layer when xfr completes */ | ||
541 | static void bdc_req_complete(struct bdc_ep *ep, struct bdc_req *req, | ||
542 | int status) | ||
543 | { | ||
544 | struct bdc *bdc = ep->bdc; | ||
545 | |||
546 | if (req == NULL || &req->queue == NULL || &req->usb_req == NULL) | ||
547 | return; | ||
548 | |||
549 | dev_dbg(bdc->dev, "%s ep:%s status:%d\n", __func__, ep->name, status); | ||
550 | list_del(&req->queue); | ||
551 | req->usb_req.status = status; | ||
552 | usb_gadget_unmap_request(&bdc->gadget, &req->usb_req, ep->dir); | ||
553 | if (req->usb_req.complete) { | ||
554 | spin_unlock(&bdc->lock); | ||
555 | usb_gadget_giveback_request(&ep->usb_ep, &req->usb_req); | ||
556 | spin_lock(&bdc->lock); | ||
557 | } | ||
558 | } | ||
559 | |||
560 | /* Disable the endpoint */ | ||
561 | int bdc_ep_disable(struct bdc_ep *ep) | ||
562 | { | ||
563 | struct bdc_req *req; | ||
564 | struct bdc *bdc; | ||
565 | int ret; | ||
566 | |||
567 | ret = 0; | ||
568 | bdc = ep->bdc; | ||
569 | dev_dbg(bdc->dev, "%s() ep->ep_num=%d\n", __func__, ep->ep_num); | ||
570 | /* Stop the endpoint */ | ||
571 | ret = bdc_stop_ep(bdc, ep->ep_num); | ||
572 | |||
573 | /* | ||
574 | * Intentionally don't check the ret value of stop, it can fail in | ||
575 | * disconnect scenarios, continue with dconfig | ||
576 | */ | ||
577 | /* de-queue any pending requests */ | ||
578 | while (!list_empty(&ep->queue)) { | ||
579 | req = list_entry(ep->queue.next, struct bdc_req, | ||
580 | queue); | ||
581 | bdc_req_complete(ep, req, -ESHUTDOWN); | ||
582 | } | ||
583 | /* deconfigure the endpoint */ | ||
584 | ret = bdc_dconfig_ep(bdc, ep); | ||
585 | if (ret) | ||
586 | dev_warn(bdc->dev, | ||
587 | "dconfig fail but continue with memory free"); | ||
588 | |||
589 | ep->flags = 0; | ||
590 | /* ep0 memory is not freed, but reused on next connect sr */ | ||
591 | if (ep->ep_num == 1) | ||
592 | return 0; | ||
593 | |||
594 | /* Free the bdl memory */ | ||
595 | ep_bd_list_free(ep, ep->bd_list.num_tabs); | ||
596 | ep->desc = NULL; | ||
597 | ep->comp_desc = NULL; | ||
598 | ep->usb_ep.desc = NULL; | ||
599 | ep->ep_type = 0; | ||
600 | |||
601 | return ret; | ||
602 | } | ||
603 | |||
604 | /* Enable the ep */ | ||
605 | int bdc_ep_enable(struct bdc_ep *ep) | ||
606 | { | ||
607 | struct bdc *bdc; | ||
608 | int ret = 0; | ||
609 | |||
610 | bdc = ep->bdc; | ||
611 | dev_dbg(bdc->dev, "%s NUM_TABLES:%d %d\n", | ||
612 | __func__, NUM_TABLES, NUM_TABLES_ISOCH); | ||
613 | |||
614 | ret = ep_bd_list_alloc(ep); | ||
615 | if (ret) { | ||
616 | dev_err(bdc->dev, "ep bd list allocation failed:%d\n", ret); | ||
617 | return -ENOMEM; | ||
618 | } | ||
619 | bdc_dbg_bd_list(bdc, ep); | ||
620 | /* only for ep0: config ep is called for ep0 from connect event */ | ||
621 | ep->flags |= BDC_EP_ENABLED; | ||
622 | if (ep->ep_num == 1) | ||
623 | return ret; | ||
624 | |||
625 | /* Issue a configure endpoint command */ | ||
626 | ret = bdc_config_ep(bdc, ep); | ||
627 | if (ret) | ||
628 | return ret; | ||
629 | |||
630 | ep->usb_ep.maxpacket = usb_endpoint_maxp(ep->desc); | ||
631 | ep->usb_ep.desc = ep->desc; | ||
632 | ep->usb_ep.comp_desc = ep->comp_desc; | ||
633 | ep->ep_type = usb_endpoint_type(ep->desc); | ||
634 | ep->flags |= BDC_EP_ENABLED; | ||
635 | |||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | /* EP0 related code */ | ||
640 | |||
641 | /* Queue a status stage BD */ | ||
642 | static int ep0_queue_status_stage(struct bdc *bdc) | ||
643 | { | ||
644 | struct bdc_req *status_req; | ||
645 | struct bdc_ep *ep; | ||
646 | |||
647 | status_req = &bdc->status_req; | ||
648 | ep = bdc->bdc_ep_array[1]; | ||
649 | status_req->ep = ep; | ||
650 | status_req->usb_req.length = 0; | ||
651 | status_req->usb_req.status = -EINPROGRESS; | ||
652 | status_req->usb_req.actual = 0; | ||
653 | status_req->usb_req.complete = NULL; | ||
654 | bdc_queue_xfr(bdc, status_req); | ||
655 | |||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | /* Queue xfr on ep0 */ | ||
660 | static int ep0_queue(struct bdc_ep *ep, struct bdc_req *req) | ||
661 | { | ||
662 | struct bdc *bdc; | ||
663 | int ret; | ||
664 | |||
665 | bdc = ep->bdc; | ||
666 | dev_dbg(bdc->dev, "%s()\n", __func__); | ||
667 | req->usb_req.actual = 0; | ||
668 | req->usb_req.status = -EINPROGRESS; | ||
669 | req->epnum = ep->ep_num; | ||
670 | |||
671 | if (bdc->delayed_status) { | ||
672 | bdc->delayed_status = false; | ||
673 | /* if status stage was delayed? */ | ||
674 | if (bdc->ep0_state == WAIT_FOR_STATUS_START) { | ||
675 | /* Queue a status stage BD */ | ||
676 | ep0_queue_status_stage(bdc); | ||
677 | bdc->ep0_state = WAIT_FOR_STATUS_XMIT; | ||
678 | return 0; | ||
679 | } | ||
680 | } else { | ||
681 | /* | ||
682 | * if delayed status is false and 0 length transfer is requested | ||
683 | * i.e. for status stage of some setup request, then just | ||
684 | * return from here the status stage is queued independently | ||
685 | */ | ||
686 | if (req->usb_req.length == 0) | ||
687 | return 0; | ||
688 | |||
689 | } | ||
690 | ret = usb_gadget_map_request(&bdc->gadget, &req->usb_req, ep->dir); | ||
691 | if (ret) { | ||
692 | dev_err(bdc->dev, "dma mapping failed %s\n", ep->name); | ||
693 | return ret; | ||
694 | } | ||
695 | |||
696 | return bdc_queue_xfr(bdc, req); | ||
697 | } | ||
698 | |||
699 | /* Queue data stage */ | ||
700 | static int ep0_queue_data_stage(struct bdc *bdc) | ||
701 | { | ||
702 | struct usb_request *ep0_usb_req; | ||
703 | struct bdc_ep *ep; | ||
704 | |||
705 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
706 | ep0_usb_req = &bdc->ep0_req.usb_req; | ||
707 | ep = bdc->bdc_ep_array[1]; | ||
708 | bdc->ep0_req.ep = ep; | ||
709 | bdc->ep0_req.usb_req.complete = NULL; | ||
710 | |||
711 | return ep0_queue(ep, &bdc->ep0_req); | ||
712 | } | ||
713 | |||
714 | /* Queue req on ep */ | ||
715 | static int ep_queue(struct bdc_ep *ep, struct bdc_req *req) | ||
716 | { | ||
717 | struct bdc *bdc; | ||
718 | int ret = 0; | ||
719 | |||
720 | bdc = ep->bdc; | ||
721 | if (!req || !ep || !ep->usb_ep.desc) | ||
722 | return -EINVAL; | ||
723 | |||
724 | req->usb_req.actual = 0; | ||
725 | req->usb_req.status = -EINPROGRESS; | ||
726 | req->epnum = ep->ep_num; | ||
727 | |||
728 | ret = usb_gadget_map_request(&bdc->gadget, &req->usb_req, ep->dir); | ||
729 | if (ret) { | ||
730 | dev_err(bdc->dev, "dma mapping failed\n"); | ||
731 | return ret; | ||
732 | } | ||
733 | |||
734 | return bdc_queue_xfr(bdc, req); | ||
735 | } | ||
736 | |||
737 | /* Dequeue a request from ep */ | ||
738 | static int ep_dequeue(struct bdc_ep *ep, struct bdc_req *req) | ||
739 | { | ||
740 | int start_bdi, end_bdi, tbi, eqp_bdi, curr_hw_dqpi; | ||
741 | bool start_pending, end_pending; | ||
742 | bool first_remove = false; | ||
743 | struct bdc_req *first_req; | ||
744 | struct bdc_bd *bd_start; | ||
745 | struct bd_table *table; | ||
746 | dma_addr_t next_bd_dma; | ||
747 | u64 deq_ptr_64 = 0; | ||
748 | struct bdc *bdc; | ||
749 | u32 tmp_32; | ||
750 | int ret; | ||
751 | |||
752 | bdc = ep->bdc; | ||
753 | start_pending = end_pending = false; | ||
754 | eqp_bdi = ep->bd_list.eqp_bdi - 1; | ||
755 | |||
756 | if (eqp_bdi < 0) | ||
757 | eqp_bdi = ep->bd_list.max_bdi; | ||
758 | |||
759 | start_bdi = req->bd_xfr.start_bdi; | ||
760 | end_bdi = find_end_bdi(ep, req->bd_xfr.next_hwd_bdi); | ||
761 | |||
762 | dev_dbg(bdc->dev, "%s ep:%s start:%d end:%d\n", | ||
763 | __func__, ep->name, start_bdi, end_bdi); | ||
764 | dev_dbg(bdc->dev, "ep_dequeue ep=%p ep->desc=%p\n", | ||
765 | ep, (void *)ep->usb_ep.desc); | ||
766 | /* Stop the ep to see where the HW is ? */ | ||
767 | ret = bdc_stop_ep(bdc, ep->ep_num); | ||
768 | /* if there is an issue with stopping ep, then no need to go further */ | ||
769 | if (ret) | ||
770 | return 0; | ||
771 | |||
772 | /* | ||
773 | * After endpoint is stopped, there can be 3 cases, the request | ||
774 | * is processed, pending or in the middle of processing | ||
775 | */ | ||
776 | |||
777 | /* The current hw dequeue pointer */ | ||
778 | tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0(0)); | ||
779 | deq_ptr_64 = tmp_32; | ||
780 | tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0(1)); | ||
781 | deq_ptr_64 |= ((u64)tmp_32 << 32); | ||
782 | |||
783 | /* we have the dma addr of next bd that will be fetched by hardware */ | ||
784 | curr_hw_dqpi = bd_add_to_bdi(ep, deq_ptr_64); | ||
785 | if (curr_hw_dqpi < 0) | ||
786 | return curr_hw_dqpi; | ||
787 | |||
788 | /* | ||
789 | * curr_hw_dqpi points to actual dqp of HW and HW owns bd's from | ||
790 | * curr_hw_dqbdi..eqp_bdi. | ||
791 | */ | ||
792 | |||
793 | /* Check if start_bdi and end_bdi are in range of HW owned BD's */ | ||
794 | if (curr_hw_dqpi > eqp_bdi) { | ||
795 | /* there is a wrap from last to 0 */ | ||
796 | if (start_bdi >= curr_hw_dqpi || start_bdi <= eqp_bdi) { | ||
797 | start_pending = true; | ||
798 | end_pending = true; | ||
799 | } else if (end_bdi >= curr_hw_dqpi || end_bdi <= eqp_bdi) { | ||
800 | end_pending = true; | ||
801 | } | ||
802 | } else { | ||
803 | if (start_bdi >= curr_hw_dqpi) { | ||
804 | start_pending = true; | ||
805 | end_pending = true; | ||
806 | } else if (end_bdi >= curr_hw_dqpi) { | ||
807 | end_pending = true; | ||
808 | } | ||
809 | } | ||
810 | dev_dbg(bdc->dev, | ||
811 | "start_pending:%d end_pending:%d speed:%d\n", | ||
812 | start_pending, end_pending, bdc->gadget.speed); | ||
813 | |||
814 | /* If both start till end are processes, we cannot deq req */ | ||
815 | if (!start_pending && !end_pending) | ||
816 | return -EINVAL; | ||
817 | |||
818 | /* | ||
819 | * if ep_dequeue is called after disconnect then just return | ||
820 | * success from here | ||
821 | */ | ||
822 | if (bdc->gadget.speed == USB_SPEED_UNKNOWN) | ||
823 | return 0; | ||
824 | tbi = bdi_to_tbi(ep, req->bd_xfr.next_hwd_bdi); | ||
825 | table = ep->bd_list.bd_table_array[tbi]; | ||
826 | next_bd_dma = table->dma + | ||
827 | sizeof(struct bdc_bd)*(req->bd_xfr.next_hwd_bdi - | ||
828 | tbi * ep->bd_list.num_bds_table); | ||
829 | |||
830 | first_req = list_first_entry(&ep->queue, struct bdc_req, | ||
831 | queue); | ||
832 | |||
833 | if (req == first_req) | ||
834 | first_remove = true; | ||
835 | |||
836 | /* | ||
837 | * Due to HW limitation we need to bypadd chain bd's and issue ep_bla, | ||
838 | * incase if start is pending this is the first request in the list | ||
839 | * then issue ep_bla instead of marking as chain bd | ||
840 | */ | ||
841 | if (start_pending && !first_remove) { | ||
842 | /* | ||
843 | * Mark the start bd as Chain bd, and point the chain | ||
844 | * bd to next_bd_dma | ||
845 | */ | ||
846 | bd_start = bdi_to_bd(ep, start_bdi); | ||
847 | bd_start->offset[0] = cpu_to_le32(lower_32_bits(next_bd_dma)); | ||
848 | bd_start->offset[1] = cpu_to_le32(upper_32_bits(next_bd_dma)); | ||
849 | bd_start->offset[2] = 0x0; | ||
850 | bd_start->offset[3] = cpu_to_le32(MARK_CHAIN_BD); | ||
851 | bdc_dbg_bd_list(bdc, ep); | ||
852 | } else if (end_pending) { | ||
853 | /* | ||
854 | * The transfer is stopped in the middle, move the | ||
855 | * HW deq pointer to next_bd_dma | ||
856 | */ | ||
857 | ret = bdc_ep_bla(bdc, ep, next_bd_dma); | ||
858 | if (ret) { | ||
859 | dev_err(bdc->dev, "error in ep_bla:%d\n", ret); | ||
860 | return ret; | ||
861 | } | ||
862 | } | ||
863 | |||
864 | return 0; | ||
865 | } | ||
866 | |||
867 | /* Halt/Clear the ep based on value */ | ||
868 | static int ep_set_halt(struct bdc_ep *ep, u32 value) | ||
869 | { | ||
870 | struct bdc *bdc; | ||
871 | int ret; | ||
872 | |||
873 | bdc = ep->bdc; | ||
874 | dev_dbg(bdc->dev, "%s ep:%s value=%d\n", __func__, ep->name, value); | ||
875 | |||
876 | if (value) { | ||
877 | dev_dbg(bdc->dev, "Halt\n"); | ||
878 | if (ep->ep_num == 1) | ||
879 | bdc->ep0_state = WAIT_FOR_SETUP; | ||
880 | |||
881 | ret = bdc_ep_set_stall(bdc, ep->ep_num); | ||
882 | if (ret) | ||
883 | dev_err(bdc->dev, "failed to %s STALL on %s\n", | ||
884 | value ? "set" : "clear", ep->name); | ||
885 | else | ||
886 | ep->flags |= BDC_EP_STALL; | ||
887 | } else { | ||
888 | /* Clear */ | ||
889 | dev_dbg(bdc->dev, "Before Clear\n"); | ||
890 | ret = bdc_ep_clear_stall(bdc, ep->ep_num); | ||
891 | if (ret) | ||
892 | dev_err(bdc->dev, "failed to %s STALL on %s\n", | ||
893 | value ? "set" : "clear", ep->name); | ||
894 | else | ||
895 | ep->flags &= ~BDC_EP_STALL; | ||
896 | dev_dbg(bdc->dev, "After Clear\n"); | ||
897 | } | ||
898 | |||
899 | return ret; | ||
900 | } | ||
901 | |||
902 | /* Free all the ep */ | ||
903 | void bdc_free_ep(struct bdc *bdc) | ||
904 | { | ||
905 | struct bdc_ep *ep; | ||
906 | u8 epnum; | ||
907 | |||
908 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
909 | for (epnum = 1; epnum < bdc->num_eps; epnum++) { | ||
910 | ep = bdc->bdc_ep_array[epnum]; | ||
911 | if (!ep) | ||
912 | continue; | ||
913 | |||
914 | if (ep->flags & BDC_EP_ENABLED) | ||
915 | ep_bd_list_free(ep, ep->bd_list.num_tabs); | ||
916 | |||
917 | /* ep0 is not in this gadget list */ | ||
918 | if (epnum != 1) | ||
919 | list_del(&ep->usb_ep.ep_list); | ||
920 | |||
921 | kfree(ep); | ||
922 | } | ||
923 | } | ||
924 | |||
925 | /* USB2 spec, section 7.1.20 */ | ||
926 | static int bdc_set_test_mode(struct bdc *bdc) | ||
927 | { | ||
928 | u32 usb2_pm; | ||
929 | |||
930 | usb2_pm = bdc_readl(bdc->regs, BDC_USPPM2); | ||
931 | usb2_pm &= ~BDC_PTC_MASK; | ||
932 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
933 | switch (bdc->test_mode) { | ||
934 | case TEST_J: | ||
935 | case TEST_K: | ||
936 | case TEST_SE0_NAK: | ||
937 | case TEST_PACKET: | ||
938 | case TEST_FORCE_EN: | ||
939 | usb2_pm |= bdc->test_mode << 28; | ||
940 | break; | ||
941 | default: | ||
942 | return -EINVAL; | ||
943 | } | ||
944 | dev_dbg(bdc->dev, "usb2_pm=%08x", usb2_pm); | ||
945 | bdc_writel(bdc->regs, BDC_USPPM2, usb2_pm); | ||
946 | |||
947 | return 0; | ||
948 | } | ||
949 | |||
950 | /* | ||
951 | * Helper function to handle Transfer status report with status as either | ||
952 | * success or short | ||
953 | */ | ||
954 | static void handle_xsr_succ_status(struct bdc *bdc, struct bdc_ep *ep, | ||
955 | struct bdc_sr *sreport) | ||
956 | { | ||
957 | int short_bdi, start_bdi, end_bdi, max_len_bds, chain_bds; | ||
958 | struct bd_list *bd_list = &ep->bd_list; | ||
959 | int actual_length, length_short; | ||
960 | struct bd_transfer *bd_xfr; | ||
961 | struct bdc_bd *short_bd; | ||
962 | struct bdc_req *req; | ||
963 | u64 deq_ptr_64 = 0; | ||
964 | int status = 0; | ||
965 | int sr_status; | ||
966 | u32 tmp_32; | ||
967 | |||
968 | dev_dbg(bdc->dev, "%s ep:%p\n", __func__, ep); | ||
969 | bdc_dbg_srr(bdc, 0); | ||
970 | /* do not process thie sr if ignore flag is set */ | ||
971 | if (ep->ignore_next_sr) { | ||
972 | ep->ignore_next_sr = false; | ||
973 | return; | ||
974 | } | ||
975 | |||
976 | if (unlikely(list_empty(&ep->queue))) { | ||
977 | dev_warn(bdc->dev, "xfr srr with no BD's queued\n"); | ||
978 | return; | ||
979 | } | ||
980 | req = list_entry(ep->queue.next, struct bdc_req, | ||
981 | queue); | ||
982 | |||
983 | bd_xfr = &req->bd_xfr; | ||
984 | sr_status = XSF_STS(le32_to_cpu(sreport->offset[3])); | ||
985 | |||
986 | /* | ||
987 | * sr_status is short and this transfer has more than 1 bd then it needs | ||
988 | * special handling, this is only applicable for bulk and ctrl | ||
989 | */ | ||
990 | if (sr_status == XSF_SHORT && bd_xfr->num_bds > 1) { | ||
991 | /* | ||
992 | * This is multi bd xfr, lets see which bd | ||
993 | * caused short transfer and how many bytes have been | ||
994 | * transferred so far. | ||
995 | */ | ||
996 | tmp_32 = le32_to_cpu(sreport->offset[0]); | ||
997 | deq_ptr_64 = tmp_32; | ||
998 | tmp_32 = le32_to_cpu(sreport->offset[1]); | ||
999 | deq_ptr_64 |= ((u64)tmp_32 << 32); | ||
1000 | short_bdi = bd_add_to_bdi(ep, deq_ptr_64); | ||
1001 | if (unlikely(short_bdi < 0)) | ||
1002 | dev_warn(bdc->dev, "bd doesn't exist?\n"); | ||
1003 | |||
1004 | start_bdi = bd_xfr->start_bdi; | ||
1005 | /* | ||
1006 | * We know the start_bdi and short_bdi, how many xfr | ||
1007 | * bds in between | ||
1008 | */ | ||
1009 | if (start_bdi <= short_bdi) { | ||
1010 | max_len_bds = short_bdi - start_bdi; | ||
1011 | if (max_len_bds <= bd_list->num_bds_table) { | ||
1012 | if (!(bdi_to_tbi(ep, start_bdi) == | ||
1013 | bdi_to_tbi(ep, short_bdi))) | ||
1014 | max_len_bds--; | ||
1015 | } else { | ||
1016 | chain_bds = max_len_bds/bd_list->num_bds_table; | ||
1017 | max_len_bds -= chain_bds; | ||
1018 | } | ||
1019 | } else { | ||
1020 | /* there is a wrap in the ring within a xfr */ | ||
1021 | chain_bds = (bd_list->max_bdi - start_bdi)/ | ||
1022 | bd_list->num_bds_table; | ||
1023 | chain_bds += short_bdi/bd_list->num_bds_table; | ||
1024 | max_len_bds = bd_list->max_bdi - start_bdi; | ||
1025 | max_len_bds += short_bdi; | ||
1026 | max_len_bds -= chain_bds; | ||
1027 | } | ||
1028 | /* max_len_bds is the number of full length bds */ | ||
1029 | end_bdi = find_end_bdi(ep, bd_xfr->next_hwd_bdi); | ||
1030 | if (!(end_bdi == short_bdi)) | ||
1031 | ep->ignore_next_sr = true; | ||
1032 | |||
1033 | actual_length = max_len_bds * BD_MAX_BUFF_SIZE; | ||
1034 | short_bd = bdi_to_bd(ep, short_bdi); | ||
1035 | /* length queued */ | ||
1036 | length_short = le32_to_cpu(short_bd->offset[2]) & 0x1FFFFF; | ||
1037 | /* actual length trensfered */ | ||
1038 | length_short -= SR_BD_LEN(le32_to_cpu(sreport->offset[2])); | ||
1039 | actual_length += length_short; | ||
1040 | req->usb_req.actual = actual_length; | ||
1041 | } else { | ||
1042 | req->usb_req.actual = req->usb_req.length - | ||
1043 | SR_BD_LEN(le32_to_cpu(sreport->offset[2])); | ||
1044 | dev_dbg(bdc->dev, | ||
1045 | "len=%d actual=%d bd_xfr->next_hwd_bdi:%d\n", | ||
1046 | req->usb_req.length, req->usb_req.actual, | ||
1047 | bd_xfr->next_hwd_bdi); | ||
1048 | } | ||
1049 | |||
1050 | /* Update the dequeue pointer */ | ||
1051 | ep->bd_list.hwd_bdi = bd_xfr->next_hwd_bdi; | ||
1052 | if (req->usb_req.actual < req->usb_req.length) { | ||
1053 | dev_dbg(bdc->dev, "short xfr on %d\n", ep->ep_num); | ||
1054 | if (req->usb_req.short_not_ok) | ||
1055 | status = -EREMOTEIO; | ||
1056 | } | ||
1057 | bdc_req_complete(ep, bd_xfr->req, status); | ||
1058 | } | ||
1059 | |||
1060 | /* EP0 setup related packet handlers */ | ||
1061 | |||
1062 | /* | ||
1063 | * Setup packet received, just store the packet and process on next DS or SS | ||
1064 | * started SR | ||
1065 | */ | ||
1066 | void bdc_xsf_ep0_setup_recv(struct bdc *bdc, struct bdc_sr *sreport) | ||
1067 | { | ||
1068 | struct usb_ctrlrequest *setup_pkt; | ||
1069 | u32 len; | ||
1070 | |||
1071 | dev_dbg(bdc->dev, | ||
1072 | "%s ep0_state:%s\n", | ||
1073 | __func__, ep0_state_string[bdc->ep0_state]); | ||
1074 | /* Store received setup packet */ | ||
1075 | setup_pkt = &bdc->setup_pkt; | ||
1076 | memcpy(setup_pkt, &sreport->offset[0], sizeof(*setup_pkt)); | ||
1077 | len = le16_to_cpu(setup_pkt->wLength); | ||
1078 | if (!len) | ||
1079 | bdc->ep0_state = WAIT_FOR_STATUS_START; | ||
1080 | else | ||
1081 | bdc->ep0_state = WAIT_FOR_DATA_START; | ||
1082 | |||
1083 | |||
1084 | dev_dbg(bdc->dev, | ||
1085 | "%s exit ep0_state:%s\n", | ||
1086 | __func__, ep0_state_string[bdc->ep0_state]); | ||
1087 | } | ||
1088 | |||
1089 | /* Stall ep0 */ | ||
1090 | static void ep0_stall(struct bdc *bdc) | ||
1091 | { | ||
1092 | struct bdc_ep *ep = bdc->bdc_ep_array[1]; | ||
1093 | struct bdc_req *req; | ||
1094 | |||
1095 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
1096 | bdc->delayed_status = false; | ||
1097 | ep_set_halt(ep, 1); | ||
1098 | |||
1099 | /* de-queue any pendig requests */ | ||
1100 | while (!list_empty(&ep->queue)) { | ||
1101 | req = list_entry(ep->queue.next, struct bdc_req, | ||
1102 | queue); | ||
1103 | bdc_req_complete(ep, req, -ESHUTDOWN); | ||
1104 | } | ||
1105 | } | ||
1106 | |||
1107 | /* SET_ADD handlers */ | ||
1108 | static int ep0_set_address(struct bdc *bdc, struct usb_ctrlrequest *ctrl) | ||
1109 | { | ||
1110 | enum usb_device_state state = bdc->gadget.state; | ||
1111 | int ret = 0; | ||
1112 | u32 addr; | ||
1113 | |||
1114 | addr = le16_to_cpu(ctrl->wValue); | ||
1115 | dev_dbg(bdc->dev, | ||
1116 | "%s addr:%d dev state:%d\n", | ||
1117 | __func__, addr, state); | ||
1118 | |||
1119 | if (addr > 127) | ||
1120 | return -EINVAL; | ||
1121 | |||
1122 | switch (state) { | ||
1123 | case USB_STATE_DEFAULT: | ||
1124 | case USB_STATE_ADDRESS: | ||
1125 | /* Issue Address device command */ | ||
1126 | ret = bdc_address_device(bdc, addr); | ||
1127 | if (ret) | ||
1128 | return ret; | ||
1129 | |||
1130 | if (addr) | ||
1131 | usb_gadget_set_state(&bdc->gadget, USB_STATE_ADDRESS); | ||
1132 | else | ||
1133 | usb_gadget_set_state(&bdc->gadget, USB_STATE_DEFAULT); | ||
1134 | |||
1135 | bdc->dev_addr = addr; | ||
1136 | break; | ||
1137 | default: | ||
1138 | dev_warn(bdc->dev, | ||
1139 | "SET Address in wrong device state %d\n", | ||
1140 | state); | ||
1141 | ret = -EINVAL; | ||
1142 | } | ||
1143 | |||
1144 | return ret; | ||
1145 | } | ||
1146 | |||
1147 | /* Handler for SET/CLEAR FEATURE requests for device */ | ||
1148 | static int ep0_handle_feature_dev(struct bdc *bdc, u16 wValue, | ||
1149 | u16 wIndex, bool set) | ||
1150 | { | ||
1151 | enum usb_device_state state = bdc->gadget.state; | ||
1152 | u32 usppms = 0; | ||
1153 | |||
1154 | dev_dbg(bdc->dev, "%s set:%d dev state:%d\n", | ||
1155 | __func__, set, state); | ||
1156 | switch (wValue) { | ||
1157 | case USB_DEVICE_REMOTE_WAKEUP: | ||
1158 | dev_dbg(bdc->dev, "USB_DEVICE_REMOTE_WAKEUP\n"); | ||
1159 | if (set) | ||
1160 | bdc->devstatus |= REMOTE_WAKE_ENABLE; | ||
1161 | else | ||
1162 | bdc->devstatus &= ~REMOTE_WAKE_ENABLE; | ||
1163 | break; | ||
1164 | |||
1165 | case USB_DEVICE_TEST_MODE: | ||
1166 | dev_dbg(bdc->dev, "USB_DEVICE_TEST_MODE\n"); | ||
1167 | if ((wIndex & 0xFF) || | ||
1168 | (bdc->gadget.speed != USB_SPEED_HIGH) || !set) | ||
1169 | return -EINVAL; | ||
1170 | |||
1171 | bdc->test_mode = wIndex >> 8; | ||
1172 | break; | ||
1173 | |||
1174 | case USB_DEVICE_U1_ENABLE: | ||
1175 | dev_dbg(bdc->dev, "USB_DEVICE_U1_ENABLE\n"); | ||
1176 | |||
1177 | if (bdc->gadget.speed != USB_SPEED_SUPER || | ||
1178 | state != USB_STATE_CONFIGURED) | ||
1179 | return -EINVAL; | ||
1180 | |||
1181 | usppms = bdc_readl(bdc->regs, BDC_USPPMS); | ||
1182 | if (set) { | ||
1183 | /* clear previous u1t */ | ||
1184 | usppms &= ~BDC_U1T(BDC_U1T_MASK); | ||
1185 | usppms |= BDC_U1T(U1_TIMEOUT); | ||
1186 | usppms |= BDC_U1E | BDC_PORT_W1S; | ||
1187 | bdc->devstatus |= (1 << USB_DEV_STAT_U1_ENABLED); | ||
1188 | } else { | ||
1189 | usppms &= ~BDC_U1E; | ||
1190 | usppms |= BDC_PORT_W1S; | ||
1191 | bdc->devstatus &= ~(1 << USB_DEV_STAT_U1_ENABLED); | ||
1192 | } | ||
1193 | bdc_writel(bdc->regs, BDC_USPPMS, usppms); | ||
1194 | break; | ||
1195 | |||
1196 | case USB_DEVICE_U2_ENABLE: | ||
1197 | dev_dbg(bdc->dev, "USB_DEVICE_U2_ENABLE\n"); | ||
1198 | |||
1199 | if (bdc->gadget.speed != USB_SPEED_SUPER || | ||
1200 | state != USB_STATE_CONFIGURED) | ||
1201 | return -EINVAL; | ||
1202 | |||
1203 | usppms = bdc_readl(bdc->regs, BDC_USPPMS); | ||
1204 | if (set) { | ||
1205 | usppms |= BDC_U2E; | ||
1206 | usppms |= BDC_U2A; | ||
1207 | bdc->devstatus |= (1 << USB_DEV_STAT_U2_ENABLED); | ||
1208 | } else { | ||
1209 | usppms &= ~BDC_U2E; | ||
1210 | usppms &= ~BDC_U2A; | ||
1211 | bdc->devstatus &= ~(1 << USB_DEV_STAT_U2_ENABLED); | ||
1212 | } | ||
1213 | bdc_writel(bdc->regs, BDC_USPPMS, usppms); | ||
1214 | break; | ||
1215 | |||
1216 | case USB_DEVICE_LTM_ENABLE: | ||
1217 | dev_dbg(bdc->dev, "USB_DEVICE_LTM_ENABLE?\n"); | ||
1218 | if (bdc->gadget.speed != USB_SPEED_SUPER || | ||
1219 | state != USB_STATE_CONFIGURED) | ||
1220 | return -EINVAL; | ||
1221 | break; | ||
1222 | default: | ||
1223 | dev_err(bdc->dev, "Unknown wValue:%d\n", wValue); | ||
1224 | return -EOPNOTSUPP; | ||
1225 | } /* USB_RECIP_DEVICE end */ | ||
1226 | |||
1227 | return 0; | ||
1228 | } | ||
1229 | |||
1230 | /* SET/CLEAR FEATURE handler */ | ||
1231 | static int ep0_handle_feature(struct bdc *bdc, | ||
1232 | struct usb_ctrlrequest *setup_pkt, bool set) | ||
1233 | { | ||
1234 | enum usb_device_state state = bdc->gadget.state; | ||
1235 | struct bdc_ep *ep; | ||
1236 | u16 wValue; | ||
1237 | u16 wIndex; | ||
1238 | int epnum; | ||
1239 | |||
1240 | wValue = le16_to_cpu(setup_pkt->wValue); | ||
1241 | wIndex = le16_to_cpu(setup_pkt->wIndex); | ||
1242 | |||
1243 | dev_dbg(bdc->dev, | ||
1244 | "%s wValue=%d wIndex=%d devstate=%08x speed=%d set=%d", | ||
1245 | __func__, wValue, wIndex, state, | ||
1246 | bdc->gadget.speed, set); | ||
1247 | |||
1248 | switch (setup_pkt->bRequestType & USB_RECIP_MASK) { | ||
1249 | case USB_RECIP_DEVICE: | ||
1250 | return ep0_handle_feature_dev(bdc, wValue, wIndex, set); | ||
1251 | case USB_RECIP_INTERFACE: | ||
1252 | dev_dbg(bdc->dev, "USB_RECIP_INTERFACE\n"); | ||
1253 | /* USB3 spec, sec 9.4.9 */ | ||
1254 | if (wValue != USB_INTRF_FUNC_SUSPEND) | ||
1255 | return -EINVAL; | ||
1256 | /* USB3 spec, Table 9-8 */ | ||
1257 | if (set) { | ||
1258 | if (wIndex & USB_INTRF_FUNC_SUSPEND_RW) { | ||
1259 | dev_dbg(bdc->dev, "SET REMOTE_WAKEUP\n"); | ||
1260 | bdc->devstatus |= REMOTE_WAKE_ENABLE; | ||
1261 | } else { | ||
1262 | dev_dbg(bdc->dev, "CLEAR REMOTE_WAKEUP\n"); | ||
1263 | bdc->devstatus &= ~REMOTE_WAKE_ENABLE; | ||
1264 | } | ||
1265 | } | ||
1266 | break; | ||
1267 | |||
1268 | case USB_RECIP_ENDPOINT: | ||
1269 | dev_dbg(bdc->dev, "USB_RECIP_ENDPOINT\n"); | ||
1270 | if (wValue != USB_ENDPOINT_HALT) | ||
1271 | return -EINVAL; | ||
1272 | |||
1273 | epnum = wIndex & USB_ENDPOINT_NUMBER_MASK; | ||
1274 | if (epnum) { | ||
1275 | if ((wIndex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) | ||
1276 | epnum = epnum * 2 + 1; | ||
1277 | else | ||
1278 | epnum *= 2; | ||
1279 | } else { | ||
1280 | epnum = 1; /*EP0*/ | ||
1281 | } | ||
1282 | /* | ||
1283 | * If CLEAR_FEATURE on ep0 then don't do anything as the stall | ||
1284 | * condition on ep0 has already been cleared when SETUP packet | ||
1285 | * was received. | ||
1286 | */ | ||
1287 | if (epnum == 1 && !set) { | ||
1288 | dev_dbg(bdc->dev, "ep0 stall already cleared\n"); | ||
1289 | return 0; | ||
1290 | } | ||
1291 | dev_dbg(bdc->dev, "epnum=%d\n", epnum); | ||
1292 | ep = bdc->bdc_ep_array[epnum]; | ||
1293 | if (!ep) | ||
1294 | return -EINVAL; | ||
1295 | |||
1296 | return ep_set_halt(ep, set); | ||
1297 | default: | ||
1298 | dev_err(bdc->dev, "Unknown recipient\n"); | ||
1299 | return -EINVAL; | ||
1300 | } | ||
1301 | |||
1302 | return 0; | ||
1303 | } | ||
1304 | |||
1305 | /* GET_STATUS request handler */ | ||
1306 | static int ep0_handle_status(struct bdc *bdc, | ||
1307 | struct usb_ctrlrequest *setup_pkt) | ||
1308 | { | ||
1309 | enum usb_device_state state = bdc->gadget.state; | ||
1310 | struct bdc_ep *ep; | ||
1311 | u16 usb_status = 0; | ||
1312 | u32 epnum; | ||
1313 | u16 wIndex; | ||
1314 | |||
1315 | /* USB2.0 spec sec 9.4.5 */ | ||
1316 | if (state == USB_STATE_DEFAULT) | ||
1317 | return -EINVAL; | ||
1318 | wIndex = le16_to_cpu(setup_pkt->wIndex); | ||
1319 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
1320 | usb_status = bdc->devstatus; | ||
1321 | switch (setup_pkt->bRequestType & USB_RECIP_MASK) { | ||
1322 | case USB_RECIP_DEVICE: | ||
1323 | dev_dbg(bdc->dev, | ||
1324 | "USB_RECIP_DEVICE devstatus:%08x\n", | ||
1325 | bdc->devstatus); | ||
1326 | /* USB3 spec, sec 9.4.5 */ | ||
1327 | if (bdc->gadget.speed == USB_SPEED_SUPER) | ||
1328 | usb_status &= ~REMOTE_WAKE_ENABLE; | ||
1329 | break; | ||
1330 | |||
1331 | case USB_RECIP_INTERFACE: | ||
1332 | dev_dbg(bdc->dev, "USB_RECIP_INTERFACE\n"); | ||
1333 | if (bdc->gadget.speed == USB_SPEED_SUPER) { | ||
1334 | /* | ||
1335 | * This should come from func for Func remote wkup | ||
1336 | * usb_status |=1; | ||
1337 | */ | ||
1338 | if (bdc->devstatus & REMOTE_WAKE_ENABLE) | ||
1339 | usb_status |= REMOTE_WAKE_ENABLE; | ||
1340 | } else { | ||
1341 | usb_status = 0; | ||
1342 | } | ||
1343 | |||
1344 | break; | ||
1345 | |||
1346 | case USB_RECIP_ENDPOINT: | ||
1347 | dev_dbg(bdc->dev, "USB_RECIP_ENDPOINT\n"); | ||
1348 | epnum = wIndex & USB_ENDPOINT_NUMBER_MASK; | ||
1349 | if (epnum) { | ||
1350 | if ((wIndex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) | ||
1351 | epnum = epnum*2 + 1; | ||
1352 | else | ||
1353 | epnum *= 2; | ||
1354 | } else { | ||
1355 | epnum = 1; /* EP0 */ | ||
1356 | } | ||
1357 | |||
1358 | ep = bdc->bdc_ep_array[epnum]; | ||
1359 | if (!ep) { | ||
1360 | dev_err(bdc->dev, "ISSUE, GET_STATUS for invalid EP ?"); | ||
1361 | return -EINVAL; | ||
1362 | } | ||
1363 | if (ep->flags & BDC_EP_STALL) | ||
1364 | usb_status |= 1 << USB_ENDPOINT_HALT; | ||
1365 | |||
1366 | break; | ||
1367 | default: | ||
1368 | dev_err(bdc->dev, "Unknown recipient for get_status\n"); | ||
1369 | return -EINVAL; | ||
1370 | } | ||
1371 | /* prepare a data stage for GET_STATUS */ | ||
1372 | dev_dbg(bdc->dev, "usb_status=%08x\n", usb_status); | ||
1373 | *(__le16 *)bdc->ep0_response_buff = cpu_to_le16(usb_status); | ||
1374 | bdc->ep0_req.usb_req.length = 2; | ||
1375 | bdc->ep0_req.usb_req.buf = &bdc->ep0_response_buff; | ||
1376 | ep0_queue_data_stage(bdc); | ||
1377 | |||
1378 | return 0; | ||
1379 | } | ||
1380 | |||
1381 | static void ep0_set_sel_cmpl(struct usb_ep *_ep, struct usb_request *_req) | ||
1382 | { | ||
1383 | /* ep0_set_sel_cmpl */ | ||
1384 | } | ||
1385 | |||
1386 | /* Queue data stage to handle 6 byte SET_SEL request */ | ||
1387 | static int ep0_set_sel(struct bdc *bdc, | ||
1388 | struct usb_ctrlrequest *setup_pkt) | ||
1389 | { | ||
1390 | struct bdc_ep *ep; | ||
1391 | u16 wLength; | ||
1392 | u16 wValue; | ||
1393 | |||
1394 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
1395 | wValue = le16_to_cpu(setup_pkt->wValue); | ||
1396 | wLength = le16_to_cpu(setup_pkt->wLength); | ||
1397 | if (unlikely(wLength != 6)) { | ||
1398 | dev_err(bdc->dev, "%s Wrong wLength:%d\n", __func__, wLength); | ||
1399 | return -EINVAL; | ||
1400 | } | ||
1401 | ep = bdc->bdc_ep_array[1]; | ||
1402 | bdc->ep0_req.ep = ep; | ||
1403 | bdc->ep0_req.usb_req.length = 6; | ||
1404 | bdc->ep0_req.usb_req.buf = bdc->ep0_response_buff; | ||
1405 | bdc->ep0_req.usb_req.complete = ep0_set_sel_cmpl; | ||
1406 | ep0_queue_data_stage(bdc); | ||
1407 | |||
1408 | return 0; | ||
1409 | } | ||
1410 | |||
1411 | /* | ||
1412 | * Queue a 0 byte bd only if wLength is more than the length and and length is | ||
1413 | * a multiple of MaxPacket then queue 0 byte BD | ||
1414 | */ | ||
1415 | static int ep0_queue_zlp(struct bdc *bdc) | ||
1416 | { | ||
1417 | int ret; | ||
1418 | |||
1419 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
1420 | bdc->ep0_req.ep = bdc->bdc_ep_array[1]; | ||
1421 | bdc->ep0_req.usb_req.length = 0; | ||
1422 | bdc->ep0_req.usb_req.complete = NULL; | ||
1423 | bdc->ep0_state = WAIT_FOR_DATA_START; | ||
1424 | ret = bdc_queue_xfr(bdc, &bdc->ep0_req); | ||
1425 | if (ret) { | ||
1426 | dev_err(bdc->dev, "err queueing zlp :%d\n", ret); | ||
1427 | return ret; | ||
1428 | } | ||
1429 | bdc->ep0_state = WAIT_FOR_DATA_XMIT; | ||
1430 | |||
1431 | return 0; | ||
1432 | } | ||
1433 | |||
1434 | /* Control request handler */ | ||
1435 | static int handle_control_request(struct bdc *bdc) | ||
1436 | { | ||
1437 | enum usb_device_state state = bdc->gadget.state; | ||
1438 | struct usb_ctrlrequest *setup_pkt; | ||
1439 | int delegate_setup = 0; | ||
1440 | int ret = 0; | ||
1441 | int config = 0; | ||
1442 | |||
1443 | setup_pkt = &bdc->setup_pkt; | ||
1444 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
1445 | if ((setup_pkt->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | ||
1446 | switch (setup_pkt->bRequest) { | ||
1447 | case USB_REQ_SET_ADDRESS: | ||
1448 | dev_dbg(bdc->dev, "USB_REQ_SET_ADDRESS\n"); | ||
1449 | ret = ep0_set_address(bdc, setup_pkt); | ||
1450 | bdc->devstatus &= DEVSTATUS_CLEAR; | ||
1451 | break; | ||
1452 | |||
1453 | case USB_REQ_SET_CONFIGURATION: | ||
1454 | dev_dbg(bdc->dev, "USB_REQ_SET_CONFIGURATION\n"); | ||
1455 | if (state == USB_STATE_ADDRESS) { | ||
1456 | usb_gadget_set_state(&bdc->gadget, | ||
1457 | USB_STATE_CONFIGURED); | ||
1458 | } else if (state == USB_STATE_CONFIGURED) { | ||
1459 | /* | ||
1460 | * USB2 spec sec 9.4.7, if wValue is 0 then dev | ||
1461 | * is moved to addressed state | ||
1462 | */ | ||
1463 | config = le16_to_cpu(setup_pkt->wValue); | ||
1464 | if (!config) | ||
1465 | usb_gadget_set_state( | ||
1466 | &bdc->gadget, | ||
1467 | USB_STATE_ADDRESS); | ||
1468 | } | ||
1469 | delegate_setup = 1; | ||
1470 | break; | ||
1471 | |||
1472 | case USB_REQ_SET_FEATURE: | ||
1473 | dev_dbg(bdc->dev, "USB_REQ_SET_FEATURE\n"); | ||
1474 | ret = ep0_handle_feature(bdc, setup_pkt, 1); | ||
1475 | break; | ||
1476 | |||
1477 | case USB_REQ_CLEAR_FEATURE: | ||
1478 | dev_dbg(bdc->dev, "USB_REQ_CLEAR_FEATURE\n"); | ||
1479 | ret = ep0_handle_feature(bdc, setup_pkt, 0); | ||
1480 | break; | ||
1481 | |||
1482 | case USB_REQ_GET_STATUS: | ||
1483 | dev_dbg(bdc->dev, "USB_REQ_GET_STATUS\n"); | ||
1484 | ret = ep0_handle_status(bdc, setup_pkt); | ||
1485 | break; | ||
1486 | |||
1487 | case USB_REQ_SET_SEL: | ||
1488 | dev_dbg(bdc->dev, "USB_REQ_SET_SEL\n"); | ||
1489 | ret = ep0_set_sel(bdc, setup_pkt); | ||
1490 | break; | ||
1491 | |||
1492 | case USB_REQ_SET_ISOCH_DELAY: | ||
1493 | dev_warn(bdc->dev, | ||
1494 | "USB_REQ_SET_ISOCH_DELAY not handled\n"); | ||
1495 | ret = 0; | ||
1496 | break; | ||
1497 | default: | ||
1498 | delegate_setup = 1; | ||
1499 | } | ||
1500 | } else { | ||
1501 | delegate_setup = 1; | ||
1502 | } | ||
1503 | |||
1504 | if (delegate_setup) { | ||
1505 | spin_unlock(&bdc->lock); | ||
1506 | ret = bdc->gadget_driver->setup(&bdc->gadget, setup_pkt); | ||
1507 | spin_lock(&bdc->lock); | ||
1508 | } | ||
1509 | |||
1510 | return ret; | ||
1511 | } | ||
1512 | |||
1513 | /* EP0: Data stage started */ | ||
1514 | void bdc_xsf_ep0_data_start(struct bdc *bdc, struct bdc_sr *sreport) | ||
1515 | { | ||
1516 | struct bdc_ep *ep; | ||
1517 | int ret = 0; | ||
1518 | |||
1519 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
1520 | ep = bdc->bdc_ep_array[1]; | ||
1521 | /* If ep0 was stalled, the clear it first */ | ||
1522 | if (ep->flags & BDC_EP_STALL) { | ||
1523 | ret = ep_set_halt(ep, 0); | ||
1524 | if (ret) | ||
1525 | goto err; | ||
1526 | } | ||
1527 | if (bdc->ep0_state != WAIT_FOR_DATA_START) | ||
1528 | dev_warn(bdc->dev, | ||
1529 | "Data stage not expected ep0_state:%s\n", | ||
1530 | ep0_state_string[bdc->ep0_state]); | ||
1531 | |||
1532 | ret = handle_control_request(bdc); | ||
1533 | if (ret == USB_GADGET_DELAYED_STATUS) { | ||
1534 | /* | ||
1535 | * The ep0 state will remain WAIT_FOR_DATA_START till | ||
1536 | * we received ep_queue on ep0 | ||
1537 | */ | ||
1538 | bdc->delayed_status = true; | ||
1539 | return; | ||
1540 | } | ||
1541 | if (!ret) { | ||
1542 | bdc->ep0_state = WAIT_FOR_DATA_XMIT; | ||
1543 | dev_dbg(bdc->dev, | ||
1544 | "ep0_state:%s", ep0_state_string[bdc->ep0_state]); | ||
1545 | return; | ||
1546 | } | ||
1547 | err: | ||
1548 | ep0_stall(bdc); | ||
1549 | } | ||
1550 | |||
1551 | /* EP0: status stage started */ | ||
1552 | void bdc_xsf_ep0_status_start(struct bdc *bdc, struct bdc_sr *sreport) | ||
1553 | { | ||
1554 | struct usb_ctrlrequest *setup_pkt; | ||
1555 | struct bdc_ep *ep; | ||
1556 | int ret = 0; | ||
1557 | |||
1558 | dev_dbg(bdc->dev, | ||
1559 | "%s ep0_state:%s", | ||
1560 | __func__, ep0_state_string[bdc->ep0_state]); | ||
1561 | ep = bdc->bdc_ep_array[1]; | ||
1562 | |||
1563 | /* check if ZLP was queued? */ | ||
1564 | if (bdc->zlp_needed) | ||
1565 | bdc->zlp_needed = false; | ||
1566 | |||
1567 | if (ep->flags & BDC_EP_STALL) { | ||
1568 | ret = ep_set_halt(ep, 0); | ||
1569 | if (ret) | ||
1570 | goto err; | ||
1571 | } | ||
1572 | |||
1573 | if ((bdc->ep0_state != WAIT_FOR_STATUS_START) && | ||
1574 | (bdc->ep0_state != WAIT_FOR_DATA_XMIT)) | ||
1575 | dev_err(bdc->dev, | ||
1576 | "Status stage recv but ep0_state:%s\n", | ||
1577 | ep0_state_string[bdc->ep0_state]); | ||
1578 | |||
1579 | /* check if data stage is in progress ? */ | ||
1580 | if (bdc->ep0_state == WAIT_FOR_DATA_XMIT) { | ||
1581 | bdc->ep0_state = STATUS_PENDING; | ||
1582 | /* Status stage will be queued upon Data stage transmit event */ | ||
1583 | dev_dbg(bdc->dev, | ||
1584 | "status started but data not transmitted yet\n"); | ||
1585 | return; | ||
1586 | } | ||
1587 | setup_pkt = &bdc->setup_pkt; | ||
1588 | |||
1589 | /* | ||
1590 | * 2 stage setup then only process the setup, for 3 stage setup the date | ||
1591 | * stage is already handled | ||
1592 | */ | ||
1593 | if (!le16_to_cpu(setup_pkt->wLength)) { | ||
1594 | ret = handle_control_request(bdc); | ||
1595 | if (ret == USB_GADGET_DELAYED_STATUS) { | ||
1596 | bdc->delayed_status = true; | ||
1597 | /* ep0_state will remain WAIT_FOR_STATUS_START */ | ||
1598 | return; | ||
1599 | } | ||
1600 | } | ||
1601 | if (!ret) { | ||
1602 | /* Queue a status stage BD */ | ||
1603 | ep0_queue_status_stage(bdc); | ||
1604 | bdc->ep0_state = WAIT_FOR_STATUS_XMIT; | ||
1605 | dev_dbg(bdc->dev, | ||
1606 | "ep0_state:%s", ep0_state_string[bdc->ep0_state]); | ||
1607 | return; | ||
1608 | } | ||
1609 | err: | ||
1610 | ep0_stall(bdc); | ||
1611 | } | ||
1612 | |||
1613 | /* Helper function to update ep0 upon SR with xsf_succ or xsf_short */ | ||
1614 | static void ep0_xsf_complete(struct bdc *bdc, struct bdc_sr *sreport) | ||
1615 | { | ||
1616 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
1617 | switch (bdc->ep0_state) { | ||
1618 | case WAIT_FOR_DATA_XMIT: | ||
1619 | bdc->ep0_state = WAIT_FOR_STATUS_START; | ||
1620 | break; | ||
1621 | case WAIT_FOR_STATUS_XMIT: | ||
1622 | bdc->ep0_state = WAIT_FOR_SETUP; | ||
1623 | if (bdc->test_mode) { | ||
1624 | int ret; | ||
1625 | |||
1626 | dev_dbg(bdc->dev, "test_mode:%d\n", bdc->test_mode); | ||
1627 | ret = bdc_set_test_mode(bdc); | ||
1628 | if (ret < 0) { | ||
1629 | dev_err(bdc->dev, "Err in setting Test mode\n"); | ||
1630 | return; | ||
1631 | } | ||
1632 | bdc->test_mode = 0; | ||
1633 | } | ||
1634 | break; | ||
1635 | case STATUS_PENDING: | ||
1636 | bdc_xsf_ep0_status_start(bdc, sreport); | ||
1637 | break; | ||
1638 | |||
1639 | default: | ||
1640 | dev_err(bdc->dev, | ||
1641 | "Unknown ep0_state:%s\n", | ||
1642 | ep0_state_string[bdc->ep0_state]); | ||
1643 | |||
1644 | } | ||
1645 | } | ||
1646 | |||
1647 | /* xfr completion status report handler */ | ||
1648 | void bdc_sr_xsf(struct bdc *bdc, struct bdc_sr *sreport) | ||
1649 | { | ||
1650 | struct bdc_ep *ep; | ||
1651 | u32 sr_status; | ||
1652 | u8 ep_num; | ||
1653 | |||
1654 | ep_num = (le32_to_cpu(sreport->offset[3])>>4) & 0x1f; | ||
1655 | ep = bdc->bdc_ep_array[ep_num]; | ||
1656 | if (!ep || !(ep->flags & BDC_EP_ENABLED)) { | ||
1657 | dev_err(bdc->dev, "xsf for ep not enabled\n"); | ||
1658 | return; | ||
1659 | } | ||
1660 | /* | ||
1661 | * check if this transfer is after link went from U3->U0 due | ||
1662 | * to remote wakeup | ||
1663 | */ | ||
1664 | if (bdc->devstatus & FUNC_WAKE_ISSUED) { | ||
1665 | bdc->devstatus &= ~(FUNC_WAKE_ISSUED); | ||
1666 | dev_dbg(bdc->dev, "%s clearing FUNC_WAKE_ISSUED flag\n", | ||
1667 | __func__); | ||
1668 | } | ||
1669 | sr_status = XSF_STS(le32_to_cpu(sreport->offset[3])); | ||
1670 | dev_dbg_ratelimited(bdc->dev, "%s sr_status=%d ep:%s\n", | ||
1671 | __func__, sr_status, ep->name); | ||
1672 | |||
1673 | switch (sr_status) { | ||
1674 | case XSF_SUCC: | ||
1675 | case XSF_SHORT: | ||
1676 | handle_xsr_succ_status(bdc, ep, sreport); | ||
1677 | if (ep_num == 1) | ||
1678 | ep0_xsf_complete(bdc, sreport); | ||
1679 | break; | ||
1680 | |||
1681 | case XSF_SETUP_RECV: | ||
1682 | case XSF_DATA_START: | ||
1683 | case XSF_STATUS_START: | ||
1684 | if (ep_num != 1) { | ||
1685 | dev_err(bdc->dev, | ||
1686 | "ep0 related packets on non ep0 endpoint"); | ||
1687 | return; | ||
1688 | } | ||
1689 | bdc->sr_xsf_ep0[sr_status - XSF_SETUP_RECV](bdc, sreport); | ||
1690 | break; | ||
1691 | |||
1692 | case XSF_BABB: | ||
1693 | if (ep_num == 1) { | ||
1694 | dev_dbg(bdc->dev, "Babble on ep0 zlp_need:%d\n", | ||
1695 | bdc->zlp_needed); | ||
1696 | /* | ||
1697 | * If the last completed transfer had wLength >Data Len, | ||
1698 | * and Len is multiple of MaxPacket,then queue ZLP | ||
1699 | */ | ||
1700 | if (bdc->zlp_needed) { | ||
1701 | /* queue 0 length bd */ | ||
1702 | ep0_queue_zlp(bdc); | ||
1703 | return; | ||
1704 | } | ||
1705 | } | ||
1706 | dev_warn(bdc->dev, "Babble on ep not handled\n"); | ||
1707 | break; | ||
1708 | default: | ||
1709 | dev_warn(bdc->dev, "sr status not handled:%x\n", sr_status); | ||
1710 | break; | ||
1711 | } | ||
1712 | } | ||
1713 | |||
1714 | static int bdc_gadget_ep_queue(struct usb_ep *_ep, | ||
1715 | struct usb_request *_req, gfp_t gfp_flags) | ||
1716 | { | ||
1717 | struct bdc_req *req; | ||
1718 | unsigned long flags; | ||
1719 | struct bdc_ep *ep; | ||
1720 | struct bdc *bdc; | ||
1721 | int ret; | ||
1722 | |||
1723 | if (!_ep || !_ep->desc) | ||
1724 | return -ESHUTDOWN; | ||
1725 | |||
1726 | if (!_req || !_req->complete || !_req->buf) | ||
1727 | return -EINVAL; | ||
1728 | |||
1729 | ep = to_bdc_ep(_ep); | ||
1730 | req = to_bdc_req(_req); | ||
1731 | bdc = ep->bdc; | ||
1732 | dev_dbg(bdc->dev, "%s ep:%p req:%p\n", __func__, ep, req); | ||
1733 | dev_dbg(bdc->dev, "queuing request %p to %s length %d zero:%d\n", | ||
1734 | _req, ep->name, _req->length, _req->zero); | ||
1735 | |||
1736 | if (!ep->usb_ep.desc) { | ||
1737 | dev_warn(bdc->dev, | ||
1738 | "trying to queue req %p to disabled %s\n", | ||
1739 | _req, ep->name); | ||
1740 | return -ESHUTDOWN; | ||
1741 | } | ||
1742 | |||
1743 | if (_req->length > MAX_XFR_LEN) { | ||
1744 | dev_warn(bdc->dev, | ||
1745 | "req length > supported MAX:%d requested:%d\n", | ||
1746 | MAX_XFR_LEN, _req->length); | ||
1747 | return -EOPNOTSUPP; | ||
1748 | } | ||
1749 | spin_lock_irqsave(&bdc->lock, flags); | ||
1750 | if (ep == bdc->bdc_ep_array[1]) | ||
1751 | ret = ep0_queue(ep, req); | ||
1752 | else | ||
1753 | ret = ep_queue(ep, req); | ||
1754 | |||
1755 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
1756 | |||
1757 | return ret; | ||
1758 | } | ||
1759 | |||
1760 | static int bdc_gadget_ep_dequeue(struct usb_ep *_ep, | ||
1761 | struct usb_request *_req) | ||
1762 | { | ||
1763 | struct bdc_req *req; | ||
1764 | unsigned long flags; | ||
1765 | struct bdc_ep *ep; | ||
1766 | struct bdc *bdc; | ||
1767 | int ret; | ||
1768 | |||
1769 | if (!_ep || !_req) | ||
1770 | return -EINVAL; | ||
1771 | |||
1772 | ep = to_bdc_ep(_ep); | ||
1773 | req = to_bdc_req(_req); | ||
1774 | bdc = ep->bdc; | ||
1775 | dev_dbg(bdc->dev, "%s ep:%s req:%p\n", __func__, ep->name, req); | ||
1776 | bdc_dbg_bd_list(bdc, ep); | ||
1777 | spin_lock_irqsave(&bdc->lock, flags); | ||
1778 | /* make sure it's still queued on this endpoint */ | ||
1779 | list_for_each_entry(req, &ep->queue, queue) { | ||
1780 | if (&req->usb_req == _req) | ||
1781 | break; | ||
1782 | } | ||
1783 | if (&req->usb_req != _req) { | ||
1784 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
1785 | dev_err(bdc->dev, "usb_req !=req n"); | ||
1786 | return -EINVAL; | ||
1787 | } | ||
1788 | ret = ep_dequeue(ep, req); | ||
1789 | if (ret) { | ||
1790 | ret = -EOPNOTSUPP; | ||
1791 | goto err; | ||
1792 | } | ||
1793 | bdc_req_complete(ep, req, -ECONNRESET); | ||
1794 | |||
1795 | err: | ||
1796 | bdc_dbg_bd_list(bdc, ep); | ||
1797 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
1798 | |||
1799 | return ret; | ||
1800 | } | ||
1801 | |||
1802 | static int bdc_gadget_ep_set_halt(struct usb_ep *_ep, int value) | ||
1803 | { | ||
1804 | unsigned long flags; | ||
1805 | struct bdc_ep *ep; | ||
1806 | struct bdc *bdc; | ||
1807 | int ret; | ||
1808 | |||
1809 | ep = to_bdc_ep(_ep); | ||
1810 | bdc = ep->bdc; | ||
1811 | dev_dbg(bdc->dev, "%s ep:%s value=%d\n", __func__, ep->name, value); | ||
1812 | spin_lock_irqsave(&bdc->lock, flags); | ||
1813 | if (usb_endpoint_xfer_isoc(ep->usb_ep.desc)) | ||
1814 | ret = -EINVAL; | ||
1815 | else if (!list_empty(&ep->queue)) | ||
1816 | ret = -EAGAIN; | ||
1817 | else | ||
1818 | ret = ep_set_halt(ep, value); | ||
1819 | |||
1820 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
1821 | |||
1822 | return ret; | ||
1823 | } | ||
1824 | |||
1825 | static struct usb_request *bdc_gadget_alloc_request(struct usb_ep *_ep, | ||
1826 | gfp_t gfp_flags) | ||
1827 | { | ||
1828 | struct bdc_req *req; | ||
1829 | struct bdc_ep *ep; | ||
1830 | |||
1831 | req = kzalloc(sizeof(*req), gfp_flags); | ||
1832 | if (!req) | ||
1833 | return NULL; | ||
1834 | |||
1835 | ep = to_bdc_ep(_ep); | ||
1836 | req->ep = ep; | ||
1837 | req->epnum = ep->ep_num; | ||
1838 | req->usb_req.dma = DMA_ADDR_INVALID; | ||
1839 | dev_dbg(ep->bdc->dev, "%s ep:%s req:%p\n", __func__, ep->name, req); | ||
1840 | |||
1841 | return &req->usb_req; | ||
1842 | } | ||
1843 | |||
1844 | static void bdc_gadget_free_request(struct usb_ep *_ep, | ||
1845 | struct usb_request *_req) | ||
1846 | { | ||
1847 | struct bdc_req *req; | ||
1848 | |||
1849 | req = to_bdc_req(_req); | ||
1850 | kfree(req); | ||
1851 | } | ||
1852 | |||
1853 | /* endpoint operations */ | ||
1854 | |||
1855 | /* configure endpoint and also allocate resources */ | ||
1856 | static int bdc_gadget_ep_enable(struct usb_ep *_ep, | ||
1857 | const struct usb_endpoint_descriptor *desc) | ||
1858 | { | ||
1859 | unsigned long flags; | ||
1860 | struct bdc_ep *ep; | ||
1861 | struct bdc *bdc; | ||
1862 | int ret; | ||
1863 | |||
1864 | if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) { | ||
1865 | pr_debug("bdc_gadget_ep_enable invalid parameters\n"); | ||
1866 | return -EINVAL; | ||
1867 | } | ||
1868 | |||
1869 | if (!desc->wMaxPacketSize) { | ||
1870 | pr_debug("bdc_gadget_ep_enable missing wMaxPacketSize\n"); | ||
1871 | return -EINVAL; | ||
1872 | } | ||
1873 | |||
1874 | ep = to_bdc_ep(_ep); | ||
1875 | bdc = ep->bdc; | ||
1876 | |||
1877 | /* Sanity check, upper layer will not send enable for ep0 */ | ||
1878 | if (ep == bdc->bdc_ep_array[1]) | ||
1879 | return -EINVAL; | ||
1880 | |||
1881 | if (!bdc->gadget_driver | ||
1882 | || bdc->gadget.speed == USB_SPEED_UNKNOWN) { | ||
1883 | return -ESHUTDOWN; | ||
1884 | } | ||
1885 | |||
1886 | dev_dbg(bdc->dev, "%s Enabling %s\n", __func__, ep->name); | ||
1887 | spin_lock_irqsave(&bdc->lock, flags); | ||
1888 | ep->desc = desc; | ||
1889 | ep->comp_desc = _ep->comp_desc; | ||
1890 | ret = bdc_ep_enable(ep); | ||
1891 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
1892 | |||
1893 | return ret; | ||
1894 | } | ||
1895 | |||
1896 | static int bdc_gadget_ep_disable(struct usb_ep *_ep) | ||
1897 | { | ||
1898 | unsigned long flags; | ||
1899 | struct bdc_ep *ep; | ||
1900 | struct bdc *bdc; | ||
1901 | int ret; | ||
1902 | |||
1903 | if (!_ep) { | ||
1904 | pr_debug("bdc: invalid parameters\n"); | ||
1905 | return -EINVAL; | ||
1906 | } | ||
1907 | ep = to_bdc_ep(_ep); | ||
1908 | bdc = ep->bdc; | ||
1909 | |||
1910 | /* Upper layer will not call this for ep0, but do a sanity check */ | ||
1911 | if (ep == bdc->bdc_ep_array[1]) { | ||
1912 | dev_warn(bdc->dev, "%s called for ep0\n", __func__); | ||
1913 | return -EINVAL; | ||
1914 | } | ||
1915 | dev_dbg(bdc->dev, | ||
1916 | "%s() ep:%s ep->flags:%08x\n", | ||
1917 | __func__, ep->name, ep->flags); | ||
1918 | |||
1919 | if (!(ep->flags & BDC_EP_ENABLED)) { | ||
1920 | dev_warn(bdc->dev, "%s is already disabled\n", ep->name); | ||
1921 | return 0; | ||
1922 | } | ||
1923 | spin_lock_irqsave(&bdc->lock, flags); | ||
1924 | ret = bdc_ep_disable(ep); | ||
1925 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
1926 | |||
1927 | return ret; | ||
1928 | } | ||
1929 | |||
1930 | static const struct usb_ep_ops bdc_gadget_ep_ops = { | ||
1931 | .enable = bdc_gadget_ep_enable, | ||
1932 | .disable = bdc_gadget_ep_disable, | ||
1933 | .alloc_request = bdc_gadget_alloc_request, | ||
1934 | .free_request = bdc_gadget_free_request, | ||
1935 | .queue = bdc_gadget_ep_queue, | ||
1936 | .dequeue = bdc_gadget_ep_dequeue, | ||
1937 | .set_halt = bdc_gadget_ep_set_halt | ||
1938 | }; | ||
1939 | |||
1940 | /* dir = 1 is IN */ | ||
1941 | static int init_ep(struct bdc *bdc, u32 epnum, u32 dir) | ||
1942 | { | ||
1943 | struct bdc_ep *ep; | ||
1944 | |||
1945 | dev_dbg(bdc->dev, "%s epnum=%d dir=%d\n", __func__, epnum, dir); | ||
1946 | ep = kzalloc(sizeof(*ep), GFP_KERNEL); | ||
1947 | if (!ep) | ||
1948 | return -ENOMEM; | ||
1949 | |||
1950 | ep->bdc = bdc; | ||
1951 | ep->dir = dir; | ||
1952 | |||
1953 | /* ep->ep_num is the index inside bdc_ep */ | ||
1954 | if (epnum == 1) { | ||
1955 | ep->ep_num = 1; | ||
1956 | bdc->bdc_ep_array[ep->ep_num] = ep; | ||
1957 | snprintf(ep->name, sizeof(ep->name), "ep%d", epnum - 1); | ||
1958 | usb_ep_set_maxpacket_limit(&ep->usb_ep, EP0_MAX_PKT_SIZE); | ||
1959 | ep->comp_desc = NULL; | ||
1960 | bdc->gadget.ep0 = &ep->usb_ep; | ||
1961 | } else { | ||
1962 | if (dir) | ||
1963 | ep->ep_num = epnum * 2 - 1; | ||
1964 | else | ||
1965 | ep->ep_num = epnum * 2 - 2; | ||
1966 | |||
1967 | bdc->bdc_ep_array[ep->ep_num] = ep; | ||
1968 | snprintf(ep->name, sizeof(ep->name), "ep%d%s", epnum - 1, | ||
1969 | dir & 1 ? "in" : "out"); | ||
1970 | |||
1971 | usb_ep_set_maxpacket_limit(&ep->usb_ep, 1024); | ||
1972 | ep->usb_ep.max_streams = 0; | ||
1973 | list_add_tail(&ep->usb_ep.ep_list, &bdc->gadget.ep_list); | ||
1974 | } | ||
1975 | ep->usb_ep.ops = &bdc_gadget_ep_ops; | ||
1976 | ep->usb_ep.name = ep->name; | ||
1977 | ep->flags = 0; | ||
1978 | ep->ignore_next_sr = false; | ||
1979 | dev_dbg(bdc->dev, "ep=%p ep->usb_ep.name=%s epnum=%d ep->epnum=%d\n", | ||
1980 | ep, ep->usb_ep.name, epnum, ep->ep_num); | ||
1981 | |||
1982 | INIT_LIST_HEAD(&ep->queue); | ||
1983 | |||
1984 | return 0; | ||
1985 | } | ||
1986 | |||
1987 | /* Init all ep */ | ||
1988 | int bdc_init_ep(struct bdc *bdc) | ||
1989 | { | ||
1990 | u8 epnum; | ||
1991 | int ret; | ||
1992 | |||
1993 | dev_dbg(bdc->dev, "%s()\n", __func__); | ||
1994 | INIT_LIST_HEAD(&bdc->gadget.ep_list); | ||
1995 | /* init ep0 */ | ||
1996 | ret = init_ep(bdc, 1, 0); | ||
1997 | if (ret) { | ||
1998 | dev_err(bdc->dev, "init ep ep0 fail %d\n", ret); | ||
1999 | return ret; | ||
2000 | } | ||
2001 | |||
2002 | for (epnum = 2; epnum <= bdc->num_eps / 2; epnum++) { | ||
2003 | /* OUT */ | ||
2004 | ret = init_ep(bdc, epnum, 0); | ||
2005 | if (ret) { | ||
2006 | dev_err(bdc->dev, | ||
2007 | "init ep failed for:%d error: %d\n", | ||
2008 | epnum, ret); | ||
2009 | return ret; | ||
2010 | } | ||
2011 | |||
2012 | /* IN */ | ||
2013 | ret = init_ep(bdc, epnum, 1); | ||
2014 | if (ret) { | ||
2015 | dev_err(bdc->dev, | ||
2016 | "init ep failed for:%d error: %d\n", | ||
2017 | epnum, ret); | ||
2018 | return ret; | ||
2019 | } | ||
2020 | } | ||
2021 | |||
2022 | return 0; | ||
2023 | } | ||
diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.h b/drivers/usb/gadget/udc/bdc/bdc_ep.h new file mode 100644 index 000000000000..8a6b36cbf2ea --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * bdc_ep.h - header for the BDC debug functions | ||
3 | * | ||
4 | * Copyright (C) 2014 Broadcom Corporation | ||
5 | * | ||
6 | * Author: Ashwini Pahuja | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | #ifndef __LINUX_BDC_EP_H__ | ||
15 | #define __LINUX_BDC_EP_H__ | ||
16 | |||
17 | int bdc_init_ep(struct bdc *); | ||
18 | int bdc_ep_disable(struct bdc_ep *); | ||
19 | int bdc_ep_enable(struct bdc_ep *); | ||
20 | void bdc_free_ep(struct bdc *); | ||
21 | |||
22 | #endif /* __LINUX_BDC_EP_H__ */ | ||
diff --git a/drivers/usb/gadget/udc/bdc/bdc_pci.c b/drivers/usb/gadget/udc/bdc/bdc_pci.c new file mode 100644 index 000000000000..02968842b359 --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_pci.c | |||
@@ -0,0 +1,132 @@ | |||
1 | /* | ||
2 | * bdc_pci.c - BRCM BDC USB3.0 device controller PCI interface file. | ||
3 | * | ||
4 | * Copyright (C) 2014 Broadcom Corporation | ||
5 | * | ||
6 | * Author: Ashwini Pahuja | ||
7 | * | ||
8 | * Based on drivers under drivers/usb/ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/pci_ids.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | |||
24 | #include "bdc.h" | ||
25 | |||
26 | #define BDC_PCI_PID 0x1570 | ||
27 | |||
28 | struct bdc_pci { | ||
29 | struct device *dev; | ||
30 | struct platform_device *bdc; | ||
31 | }; | ||
32 | |||
33 | static int bdc_setup_msi(struct pci_dev *pci) | ||
34 | { | ||
35 | int ret; | ||
36 | |||
37 | ret = pci_enable_msi(pci); | ||
38 | if (ret) { | ||
39 | pr_err("failed to allocate MSI entry\n"); | ||
40 | return ret; | ||
41 | } | ||
42 | |||
43 | return ret; | ||
44 | } | ||
45 | |||
46 | static int bdc_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) | ||
47 | { | ||
48 | struct resource res[2]; | ||
49 | struct platform_device *bdc; | ||
50 | struct bdc_pci *glue; | ||
51 | int ret = -ENOMEM; | ||
52 | |||
53 | glue = devm_kzalloc(&pci->dev, sizeof(*glue), GFP_KERNEL); | ||
54 | if (!glue) | ||
55 | return -ENOMEM; | ||
56 | |||
57 | glue->dev = &pci->dev; | ||
58 | ret = pci_enable_device(pci); | ||
59 | if (ret) { | ||
60 | dev_err(&pci->dev, "failed to enable pci device\n"); | ||
61 | return -ENODEV; | ||
62 | } | ||
63 | pci_set_master(pci); | ||
64 | |||
65 | bdc = platform_device_alloc(BRCM_BDC_NAME, PLATFORM_DEVID_AUTO); | ||
66 | if (!bdc) | ||
67 | return -ENOMEM; | ||
68 | |||
69 | memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); | ||
70 | bdc_setup_msi(pci); | ||
71 | |||
72 | res[0].start = pci_resource_start(pci, 0); | ||
73 | res[0].end = pci_resource_end(pci, 0); | ||
74 | res[0].name = BRCM_BDC_NAME; | ||
75 | res[0].flags = IORESOURCE_MEM; | ||
76 | |||
77 | res[1].start = pci->irq; | ||
78 | res[1].name = BRCM_BDC_NAME; | ||
79 | res[1].flags = IORESOURCE_IRQ; | ||
80 | |||
81 | ret = platform_device_add_resources(bdc, res, ARRAY_SIZE(res)); | ||
82 | if (ret) { | ||
83 | dev_err(&pci->dev, | ||
84 | "couldn't add resources to bdc device\n"); | ||
85 | return ret; | ||
86 | } | ||
87 | |||
88 | pci_set_drvdata(pci, glue); | ||
89 | |||
90 | dma_set_coherent_mask(&bdc->dev, pci->dev.coherent_dma_mask); | ||
91 | |||
92 | bdc->dev.dma_mask = pci->dev.dma_mask; | ||
93 | bdc->dev.dma_parms = pci->dev.dma_parms; | ||
94 | bdc->dev.parent = &pci->dev; | ||
95 | glue->bdc = bdc; | ||
96 | |||
97 | ret = platform_device_add(bdc); | ||
98 | if (ret) { | ||
99 | dev_err(&pci->dev, "failed to register bdc device\n"); | ||
100 | platform_device_put(bdc); | ||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static void bdc_pci_remove(struct pci_dev *pci) | ||
108 | { | ||
109 | struct bdc_pci *glue = pci_get_drvdata(pci); | ||
110 | |||
111 | platform_device_unregister(glue->bdc); | ||
112 | pci_disable_msi(pci); | ||
113 | } | ||
114 | |||
115 | static struct pci_device_id bdc_pci_id_table[] = { | ||
116 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, BDC_PCI_PID), }, | ||
117 | {} /* Terminating Entry */ | ||
118 | }; | ||
119 | |||
120 | MODULE_DEVICE_TABLE(pci, bdc_pci_id_table); | ||
121 | |||
122 | static struct pci_driver bdc_pci_driver = { | ||
123 | .name = "bdc-pci", | ||
124 | .id_table = bdc_pci_id_table, | ||
125 | .probe = bdc_pci_probe, | ||
126 | .remove = bdc_pci_remove, | ||
127 | }; | ||
128 | |||
129 | MODULE_AUTHOR("Ashwini Pahuja <ashwini.linux@gmail.com>"); | ||
130 | MODULE_LICENSE("GPL"); | ||
131 | MODULE_DESCRIPTION("BRCM BDC USB3 PCI Glue layer"); | ||
132 | module_pci_driver(bdc_pci_driver); | ||
diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c new file mode 100644 index 000000000000..3700ce70b0be --- /dev/null +++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c | |||
@@ -0,0 +1,587 @@ | |||
1 | /* | ||
2 | * bdc_udc.c - BRCM BDC USB3.0 device controller gagdet ops | ||
3 | * | ||
4 | * Copyright (C) 2014 Broadcom Corporation | ||
5 | * | ||
6 | * Author: Ashwini Pahuja | ||
7 | * | ||
8 | * Based on drivers under drivers/usb/gadget/udc/ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/pci.h> | ||
18 | #include <linux/dma-mapping.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/ioport.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/timer.h> | ||
27 | #include <linux/list.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/moduleparam.h> | ||
30 | #include <linux/device.h> | ||
31 | #include <linux/usb/ch9.h> | ||
32 | #include <linux/usb/gadget.h> | ||
33 | #include <linux/usb/otg.h> | ||
34 | #include <linux/pm.h> | ||
35 | #include <linux/io.h> | ||
36 | #include <linux/irq.h> | ||
37 | #include <asm/unaligned.h> | ||
38 | #include <linux/platform_device.h> | ||
39 | |||
40 | #include "bdc.h" | ||
41 | #include "bdc_ep.h" | ||
42 | #include "bdc_cmd.h" | ||
43 | #include "bdc_dbg.h" | ||
44 | |||
45 | static const struct usb_gadget_ops bdc_gadget_ops; | ||
46 | |||
47 | static const char * const conn_speed_str[] = { | ||
48 | "Not connected", | ||
49 | "Full Speed", | ||
50 | "Low Speed", | ||
51 | "High Speed", | ||
52 | "Super Speed", | ||
53 | }; | ||
54 | |||
55 | /* EP0 initial descripror */ | ||
56 | static struct usb_endpoint_descriptor bdc_gadget_ep0_desc = { | ||
57 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
58 | .bDescriptorType = USB_DT_ENDPOINT, | ||
59 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | ||
60 | .bEndpointAddress = 0, | ||
61 | .wMaxPacketSize = cpu_to_le16(EP0_MAX_PKT_SIZE), | ||
62 | }; | ||
63 | |||
64 | /* Advance the srr dqp maintained by SW */ | ||
65 | static void srr_dqp_index_advc(struct bdc *bdc, u32 srr_num) | ||
66 | { | ||
67 | struct srr *srr; | ||
68 | |||
69 | srr = &bdc->srr; | ||
70 | dev_dbg_ratelimited(bdc->dev, "srr->dqp_index:%d\n", srr->dqp_index); | ||
71 | srr->dqp_index++; | ||
72 | /* rollback to 0 if we are past the last */ | ||
73 | if (srr->dqp_index == NUM_SR_ENTRIES) | ||
74 | srr->dqp_index = 0; | ||
75 | } | ||
76 | |||
77 | /* connect sr */ | ||
78 | static void bdc_uspc_connected(struct bdc *bdc) | ||
79 | { | ||
80 | u32 speed, temp; | ||
81 | u32 usppms; | ||
82 | int ret; | ||
83 | |||
84 | temp = bdc_readl(bdc->regs, BDC_USPC); | ||
85 | speed = BDC_PSP(temp); | ||
86 | dev_dbg(bdc->dev, "%s speed=%x\n", __func__, speed); | ||
87 | switch (speed) { | ||
88 | case BDC_SPEED_SS: | ||
89 | bdc_gadget_ep0_desc.wMaxPacketSize = | ||
90 | cpu_to_le16(EP0_MAX_PKT_SIZE); | ||
91 | bdc->gadget.ep0->maxpacket = EP0_MAX_PKT_SIZE; | ||
92 | bdc->gadget.speed = USB_SPEED_SUPER; | ||
93 | /* Enable U1T in SS mode */ | ||
94 | usppms = bdc_readl(bdc->regs, BDC_USPPMS); | ||
95 | usppms &= ~BDC_U1T(0xff); | ||
96 | usppms |= BDC_U1T(U1_TIMEOUT); | ||
97 | usppms |= BDC_PORT_W1S; | ||
98 | bdc_writel(bdc->regs, BDC_USPPMS, usppms); | ||
99 | break; | ||
100 | |||
101 | case BDC_SPEED_HS: | ||
102 | bdc_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64); | ||
103 | bdc->gadget.ep0->maxpacket = 64; | ||
104 | bdc->gadget.speed = USB_SPEED_HIGH; | ||
105 | break; | ||
106 | |||
107 | case BDC_SPEED_FS: | ||
108 | bdc_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64); | ||
109 | bdc->gadget.ep0->maxpacket = 64; | ||
110 | bdc->gadget.speed = USB_SPEED_FULL; | ||
111 | break; | ||
112 | |||
113 | case BDC_SPEED_LS: | ||
114 | bdc_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(8); | ||
115 | bdc->gadget.ep0->maxpacket = 8; | ||
116 | bdc->gadget.speed = USB_SPEED_LOW; | ||
117 | break; | ||
118 | default: | ||
119 | dev_err(bdc->dev, "UNDEFINED SPEED\n"); | ||
120 | return; | ||
121 | } | ||
122 | dev_dbg(bdc->dev, "connected at %s\n", conn_speed_str[speed]); | ||
123 | /* Now we know the speed, configure ep0 */ | ||
124 | bdc->bdc_ep_array[1]->desc = &bdc_gadget_ep0_desc; | ||
125 | ret = bdc_config_ep(bdc, bdc->bdc_ep_array[1]); | ||
126 | if (ret) | ||
127 | dev_err(bdc->dev, "EP0 config failed\n"); | ||
128 | bdc->bdc_ep_array[1]->usb_ep.desc = &bdc_gadget_ep0_desc; | ||
129 | bdc->bdc_ep_array[1]->flags |= BDC_EP_ENABLED; | ||
130 | usb_gadget_set_state(&bdc->gadget, USB_STATE_DEFAULT); | ||
131 | } | ||
132 | |||
133 | /* device got disconnected */ | ||
134 | static void bdc_uspc_disconnected(struct bdc *bdc, bool reinit) | ||
135 | { | ||
136 | struct bdc_ep *ep; | ||
137 | |||
138 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
139 | /* | ||
140 | * Only stop ep0 from here, rest of the endpoints will be disabled | ||
141 | * from gadget_disconnect | ||
142 | */ | ||
143 | ep = bdc->bdc_ep_array[1]; | ||
144 | if (ep && (ep->flags & BDC_EP_ENABLED)) | ||
145 | /* if enabled then stop and remove requests */ | ||
146 | bdc_ep_disable(ep); | ||
147 | |||
148 | if (bdc->gadget_driver && bdc->gadget_driver->disconnect) { | ||
149 | spin_unlock(&bdc->lock); | ||
150 | bdc->gadget_driver->disconnect(&bdc->gadget); | ||
151 | spin_lock(&bdc->lock); | ||
152 | } | ||
153 | /* Set Unknown speed */ | ||
154 | bdc->gadget.speed = USB_SPEED_UNKNOWN; | ||
155 | bdc->devstatus &= DEVSTATUS_CLEAR; | ||
156 | bdc->delayed_status = false; | ||
157 | bdc->reinit = reinit; | ||
158 | bdc->test_mode = false; | ||
159 | } | ||
160 | |||
161 | /* TNotify wkaeup timer */ | ||
162 | static void bdc_func_wake_timer(struct work_struct *work) | ||
163 | { | ||
164 | struct bdc *bdc = container_of(work, struct bdc, func_wake_notify.work); | ||
165 | unsigned long flags; | ||
166 | |||
167 | dev_dbg(bdc->dev, "%s\n", __func__); | ||
168 | spin_lock_irqsave(&bdc->lock, flags); | ||
169 | /* | ||
170 | * Check if host has started transferring on endpoints | ||
171 | * FUNC_WAKE_ISSUED is cleared when transfer has started after resume | ||
172 | */ | ||
173 | if (bdc->devstatus & FUNC_WAKE_ISSUED) { | ||
174 | dev_dbg(bdc->dev, "FUNC_WAKE_ISSUED FLAG IS STILL SET\n"); | ||
175 | /* flag is still set, so again send func wake */ | ||
176 | bdc_function_wake_fh(bdc, 0); | ||
177 | schedule_delayed_work(&bdc->func_wake_notify, | ||
178 | msecs_to_jiffies(BDC_TNOTIFY)); | ||
179 | } | ||
180 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
181 | } | ||
182 | |||
183 | /* handler for Link state change condition */ | ||
184 | static void handle_link_state_change(struct bdc *bdc, u32 uspc) | ||
185 | { | ||
186 | u32 link_state; | ||
187 | |||
188 | dev_dbg(bdc->dev, "Link state change"); | ||
189 | link_state = BDC_PST(uspc); | ||
190 | switch (link_state) { | ||
191 | case BDC_LINK_STATE_U3: | ||
192 | if ((bdc->gadget.speed != USB_SPEED_UNKNOWN) && | ||
193 | bdc->gadget_driver->suspend) { | ||
194 | dev_dbg(bdc->dev, "Entered Suspend mode\n"); | ||
195 | spin_unlock(&bdc->lock); | ||
196 | bdc->devstatus |= DEVICE_SUSPENDED; | ||
197 | bdc->gadget_driver->suspend(&bdc->gadget); | ||
198 | spin_lock(&bdc->lock); | ||
199 | } | ||
200 | break; | ||
201 | case BDC_LINK_STATE_U0: | ||
202 | if (bdc->devstatus & REMOTE_WAKEUP_ISSUED) { | ||
203 | bdc->devstatus &= ~REMOTE_WAKEUP_ISSUED; | ||
204 | if (bdc->gadget.speed == USB_SPEED_SUPER) { | ||
205 | bdc_function_wake_fh(bdc, 0); | ||
206 | bdc->devstatus |= FUNC_WAKE_ISSUED; | ||
207 | /* | ||
208 | * Start a Notification timer and check if the | ||
209 | * Host transferred anything on any of the EPs, | ||
210 | * if not then send function wake again every | ||
211 | * TNotification secs until host initiates | ||
212 | * transfer to BDC, USB3 spec Table 8.13 | ||
213 | */ | ||
214 | schedule_delayed_work( | ||
215 | &bdc->func_wake_notify, | ||
216 | msecs_to_jiffies(BDC_TNOTIFY)); | ||
217 | dev_dbg(bdc->dev, "sched func_wake_notify\n"); | ||
218 | } | ||
219 | } | ||
220 | break; | ||
221 | |||
222 | case BDC_LINK_STATE_RESUME: | ||
223 | dev_dbg(bdc->dev, "Resumed from Suspend\n"); | ||
224 | if (bdc->devstatus & DEVICE_SUSPENDED) { | ||
225 | bdc->gadget_driver->resume(&bdc->gadget); | ||
226 | bdc->devstatus &= ~DEVICE_SUSPENDED; | ||
227 | } | ||
228 | break; | ||
229 | default: | ||
230 | dev_dbg(bdc->dev, "link state:%d\n", link_state); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | /* something changes on upstream port, handle it here */ | ||
235 | void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport) | ||
236 | { | ||
237 | u32 clear_flags = 0; | ||
238 | u32 uspc; | ||
239 | bool connected = false; | ||
240 | bool disconn = false; | ||
241 | |||
242 | uspc = bdc_readl(bdc->regs, BDC_USPC); | ||
243 | dev_dbg(bdc->dev, "%s uspc=0x%08x\n", __func__, uspc); | ||
244 | |||
245 | /* Port connect changed */ | ||
246 | if (uspc & BDC_PCC) { | ||
247 | /* Vbus not present, and not connected to Downstream port */ | ||
248 | if ((uspc & BDC_VBC) && !(uspc & BDC_VBS) && !(uspc & BDC_PCS)) | ||
249 | disconn = true; | ||
250 | else if ((uspc & BDC_PCS) && !BDC_PST(uspc)) | ||
251 | connected = true; | ||
252 | } | ||
253 | |||
254 | /* Change in VBus and VBus is present */ | ||
255 | if ((uspc & BDC_VBC) && (uspc & BDC_VBS)) { | ||
256 | if (bdc->pullup) { | ||
257 | dev_dbg(bdc->dev, "Do a softconnect\n"); | ||
258 | /* Attached state, do a softconnect */ | ||
259 | bdc_softconn(bdc); | ||
260 | usb_gadget_set_state(&bdc->gadget, USB_STATE_POWERED); | ||
261 | } | ||
262 | clear_flags = BDC_VBC; | ||
263 | } else if ((uspc & BDC_PRS) || (uspc & BDC_PRC) || disconn) { | ||
264 | /* Hot reset, warm reset, 2.0 bus reset or disconn */ | ||
265 | dev_dbg(bdc->dev, "Port reset or disconn\n"); | ||
266 | bdc_uspc_disconnected(bdc, disconn); | ||
267 | clear_flags = BDC_PCC|BDC_PCS|BDC_PRS|BDC_PRC; | ||
268 | } else if ((uspc & BDC_PSC) && (uspc & BDC_PCS)) { | ||
269 | /* Change in Link state */ | ||
270 | handle_link_state_change(bdc, uspc); | ||
271 | clear_flags = BDC_PSC|BDC_PCS; | ||
272 | } | ||
273 | |||
274 | /* | ||
275 | * In SS we might not have PRC bit set before connection, but in 2.0 | ||
276 | * the PRC bit is set before connection, so moving this condition out | ||
277 | * of bus reset to handle both SS/2.0 speeds. | ||
278 | */ | ||
279 | if (connected) { | ||
280 | /* This is the connect event for U0/L0 */ | ||
281 | dev_dbg(bdc->dev, "Connected\n"); | ||
282 | bdc_uspc_connected(bdc); | ||
283 | bdc->devstatus &= ~(DEVICE_SUSPENDED); | ||
284 | } | ||
285 | uspc = bdc_readl(bdc->regs, BDC_USPC); | ||
286 | uspc &= (~BDC_USPSC_RW); | ||
287 | dev_dbg(bdc->dev, "uspc=%x\n", uspc); | ||
288 | bdc_writel(bdc->regs, BDC_USPC, clear_flags); | ||
289 | } | ||
290 | |||
291 | /* Main interrupt handler for bdc */ | ||
292 | static irqreturn_t bdc_udc_interrupt(int irq, void *_bdc) | ||
293 | { | ||
294 | u32 eqp_index, dqp_index, sr_type, srr_int; | ||
295 | struct bdc_sr *sreport; | ||
296 | struct bdc *bdc = _bdc; | ||
297 | u32 status; | ||
298 | int ret; | ||
299 | |||
300 | spin_lock(&bdc->lock); | ||
301 | status = bdc_readl(bdc->regs, BDC_BDCSC); | ||
302 | if (!(status & BDC_GIP)) { | ||
303 | spin_unlock(&bdc->lock); | ||
304 | return IRQ_NONE; | ||
305 | } | ||
306 | srr_int = bdc_readl(bdc->regs, BDC_SRRINT(0)); | ||
307 | /* Check if the SRR IP bit it set? */ | ||
308 | if (!(srr_int & BDC_SRR_IP)) { | ||
309 | dev_warn(bdc->dev, "Global irq pending but SRR IP is 0\n"); | ||
310 | spin_unlock(&bdc->lock); | ||
311 | return IRQ_NONE; | ||
312 | } | ||
313 | eqp_index = BDC_SRR_EPI(srr_int); | ||
314 | dqp_index = BDC_SRR_DPI(srr_int); | ||
315 | dev_dbg(bdc->dev, | ||
316 | "%s eqp_index=%d dqp_index=%d srr.dqp_index=%d\n\n", | ||
317 | __func__, eqp_index, dqp_index, bdc->srr.dqp_index); | ||
318 | |||
319 | /* check for ring empty condition */ | ||
320 | if (eqp_index == dqp_index) { | ||
321 | dev_dbg(bdc->dev, "SRR empty?\n"); | ||
322 | spin_unlock(&bdc->lock); | ||
323 | return IRQ_HANDLED; | ||
324 | } | ||
325 | |||
326 | while (bdc->srr.dqp_index != eqp_index) { | ||
327 | sreport = &bdc->srr.sr_bds[bdc->srr.dqp_index]; | ||
328 | /* sreport is read before using it */ | ||
329 | rmb(); | ||
330 | sr_type = le32_to_cpu(sreport->offset[3]) & BD_TYPE_BITMASK; | ||
331 | dev_dbg_ratelimited(bdc->dev, "sr_type=%d\n", sr_type); | ||
332 | switch (sr_type) { | ||
333 | case SR_XSF: | ||
334 | bdc->sr_handler[0](bdc, sreport); | ||
335 | break; | ||
336 | |||
337 | case SR_USPC: | ||
338 | bdc->sr_handler[1](bdc, sreport); | ||
339 | break; | ||
340 | default: | ||
341 | dev_warn(bdc->dev, "SR:%d not handled\n", sr_type); | ||
342 | } | ||
343 | /* Advance the srr dqp index */ | ||
344 | srr_dqp_index_advc(bdc, 0); | ||
345 | } | ||
346 | /* update the hw dequeue pointer */ | ||
347 | srr_int = bdc_readl(bdc->regs, BDC_SRRINT(0)); | ||
348 | srr_int &= ~BDC_SRR_DPI_MASK; | ||
349 | srr_int &= ~(BDC_SRR_RWS|BDC_SRR_RST|BDC_SRR_ISR); | ||
350 | srr_int |= ((bdc->srr.dqp_index) << 16); | ||
351 | srr_int |= BDC_SRR_IP; | ||
352 | bdc_writel(bdc->regs, BDC_SRRINT(0), srr_int); | ||
353 | srr_int = bdc_readl(bdc->regs, BDC_SRRINT(0)); | ||
354 | if (bdc->reinit) { | ||
355 | ret = bdc_reinit(bdc); | ||
356 | if (ret) | ||
357 | dev_err(bdc->dev, "err in bdc reinit\n"); | ||
358 | } | ||
359 | |||
360 | spin_unlock(&bdc->lock); | ||
361 | |||
362 | return IRQ_HANDLED; | ||
363 | } | ||
364 | |||
365 | /* Gadget ops */ | ||
366 | static int bdc_udc_start(struct usb_gadget *gadget, | ||
367 | struct usb_gadget_driver *driver) | ||
368 | { | ||
369 | struct bdc *bdc = gadget_to_bdc(gadget); | ||
370 | unsigned long flags; | ||
371 | int ret = 0; | ||
372 | |||
373 | dev_dbg(bdc->dev, "%s()\n", __func__); | ||
374 | spin_lock_irqsave(&bdc->lock, flags); | ||
375 | if (bdc->gadget_driver) { | ||
376 | dev_err(bdc->dev, "%s is already bound to %s\n", | ||
377 | bdc->gadget.name, | ||
378 | bdc->gadget_driver->driver.name); | ||
379 | ret = -EBUSY; | ||
380 | goto err; | ||
381 | } | ||
382 | /* | ||
383 | * Run the controller from here and when BDC is connected to | ||
384 | * Host then driver will receive a USPC SR with VBUS present | ||
385 | * and then driver will do a softconnect. | ||
386 | */ | ||
387 | ret = bdc_run(bdc); | ||
388 | if (ret) { | ||
389 | dev_err(bdc->dev, "%s bdc run fail\n", __func__); | ||
390 | goto err; | ||
391 | } | ||
392 | bdc->gadget_driver = driver; | ||
393 | bdc->gadget.dev.driver = &driver->driver; | ||
394 | err: | ||
395 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
396 | |||
397 | return ret; | ||
398 | } | ||
399 | |||
400 | static int bdc_udc_stop(struct usb_gadget *gadget) | ||
401 | { | ||
402 | struct bdc *bdc = gadget_to_bdc(gadget); | ||
403 | unsigned long flags; | ||
404 | |||
405 | dev_dbg(bdc->dev, "%s()\n", __func__); | ||
406 | spin_lock_irqsave(&bdc->lock, flags); | ||
407 | bdc_stop(bdc); | ||
408 | bdc->gadget_driver = NULL; | ||
409 | bdc->gadget.dev.driver = NULL; | ||
410 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
411 | |||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static int bdc_udc_pullup(struct usb_gadget *gadget, int is_on) | ||
416 | { | ||
417 | struct bdc *bdc = gadget_to_bdc(gadget); | ||
418 | unsigned long flags; | ||
419 | u32 uspc; | ||
420 | |||
421 | dev_dbg(bdc->dev, "%s() is_on:%d\n", __func__, is_on); | ||
422 | if (!gadget) | ||
423 | return -EINVAL; | ||
424 | |||
425 | spin_lock_irqsave(&bdc->lock, flags); | ||
426 | if (!is_on) { | ||
427 | bdc_softdisconn(bdc); | ||
428 | bdc->pullup = false; | ||
429 | } else { | ||
430 | /* | ||
431 | * For a self powered device, we need to wait till we receive | ||
432 | * a VBUS change and Vbus present event, then if pullup flag | ||
433 | * is set, then only we present the Termintation. | ||
434 | */ | ||
435 | bdc->pullup = true; | ||
436 | /* | ||
437 | * Check if BDC is already connected to Host i.e Vbus=1, | ||
438 | * if yes, then present TERM now, this is typical for bus | ||
439 | * powered devices. | ||
440 | */ | ||
441 | uspc = bdc_readl(bdc->regs, BDC_USPC); | ||
442 | if (uspc & BDC_VBS) | ||
443 | bdc_softconn(bdc); | ||
444 | } | ||
445 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
446 | |||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static int bdc_udc_set_selfpowered(struct usb_gadget *gadget, | ||
451 | int is_self) | ||
452 | { | ||
453 | struct bdc *bdc = gadget_to_bdc(gadget); | ||
454 | unsigned long flags; | ||
455 | |||
456 | dev_dbg(bdc->dev, "%s()\n", __func__); | ||
457 | spin_lock_irqsave(&bdc->lock, flags); | ||
458 | if (!is_self) | ||
459 | bdc->devstatus |= 1 << USB_DEVICE_SELF_POWERED; | ||
460 | else | ||
461 | bdc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED); | ||
462 | |||
463 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
464 | |||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | static int bdc_udc_wakeup(struct usb_gadget *gadget) | ||
469 | { | ||
470 | struct bdc *bdc = gadget_to_bdc(gadget); | ||
471 | unsigned long flags; | ||
472 | u8 link_state; | ||
473 | u32 uspc; | ||
474 | int ret = 0; | ||
475 | |||
476 | dev_dbg(bdc->dev, | ||
477 | "%s() bdc->devstatus=%08x\n", | ||
478 | __func__, bdc->devstatus); | ||
479 | |||
480 | if (!(bdc->devstatus & REMOTE_WAKE_ENABLE)) | ||
481 | return -EOPNOTSUPP; | ||
482 | |||
483 | spin_lock_irqsave(&bdc->lock, flags); | ||
484 | uspc = bdc_readl(bdc->regs, BDC_USPC); | ||
485 | link_state = BDC_PST(uspc); | ||
486 | dev_dbg(bdc->dev, "link_state =%d portsc=%x", link_state, uspc); | ||
487 | if (link_state != BDC_LINK_STATE_U3) { | ||
488 | dev_warn(bdc->dev, | ||
489 | "can't wakeup from link state %d\n", | ||
490 | link_state); | ||
491 | ret = -EINVAL; | ||
492 | goto out; | ||
493 | } | ||
494 | if (bdc->gadget.speed == USB_SPEED_SUPER) | ||
495 | bdc->devstatus |= REMOTE_WAKEUP_ISSUED; | ||
496 | |||
497 | uspc &= ~BDC_PST_MASK; | ||
498 | uspc &= (~BDC_USPSC_RW); | ||
499 | uspc |= BDC_PST(BDC_LINK_STATE_U0); | ||
500 | uspc |= BDC_SWS; | ||
501 | bdc_writel(bdc->regs, BDC_USPC, uspc); | ||
502 | uspc = bdc_readl(bdc->regs, BDC_USPC); | ||
503 | link_state = BDC_PST(uspc); | ||
504 | dev_dbg(bdc->dev, "link_state =%d portsc=%x", link_state, uspc); | ||
505 | out: | ||
506 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
507 | |||
508 | return ret; | ||
509 | } | ||
510 | |||
511 | static const struct usb_gadget_ops bdc_gadget_ops = { | ||
512 | .wakeup = bdc_udc_wakeup, | ||
513 | .set_selfpowered = bdc_udc_set_selfpowered, | ||
514 | .pullup = bdc_udc_pullup, | ||
515 | .udc_start = bdc_udc_start, | ||
516 | .udc_stop = bdc_udc_stop, | ||
517 | }; | ||
518 | |||
519 | /* Init the gadget interface and register the udc */ | ||
520 | int bdc_udc_init(struct bdc *bdc) | ||
521 | { | ||
522 | u32 temp; | ||
523 | int ret; | ||
524 | |||
525 | dev_dbg(bdc->dev, "%s()\n", __func__); | ||
526 | bdc->gadget.ops = &bdc_gadget_ops; | ||
527 | bdc->gadget.max_speed = USB_SPEED_SUPER; | ||
528 | bdc->gadget.speed = USB_SPEED_UNKNOWN; | ||
529 | bdc->gadget.dev.parent = bdc->dev; | ||
530 | |||
531 | bdc->gadget.sg_supported = false; | ||
532 | |||
533 | |||
534 | bdc->gadget.name = BRCM_BDC_NAME; | ||
535 | ret = devm_request_irq(bdc->dev, bdc->irq, bdc_udc_interrupt, | ||
536 | IRQF_SHARED , BRCM_BDC_NAME, bdc); | ||
537 | if (ret) { | ||
538 | dev_err(bdc->dev, | ||
539 | "failed to request irq #%d %d\n", | ||
540 | bdc->irq, ret); | ||
541 | return ret; | ||
542 | } | ||
543 | |||
544 | ret = bdc_init_ep(bdc); | ||
545 | if (ret) { | ||
546 | dev_err(bdc->dev, "bdc init ep fail: %d\n", ret); | ||
547 | return ret; | ||
548 | } | ||
549 | |||
550 | ret = usb_add_gadget_udc(bdc->dev, &bdc->gadget); | ||
551 | if (ret) { | ||
552 | dev_err(bdc->dev, "failed to register udc\n"); | ||
553 | goto err0; | ||
554 | } | ||
555 | usb_gadget_set_state(&bdc->gadget, USB_STATE_NOTATTACHED); | ||
556 | bdc->bdc_ep_array[1]->desc = &bdc_gadget_ep0_desc; | ||
557 | /* | ||
558 | * Allocate bd list for ep0 only, ep0 will be enabled on connect | ||
559 | * status report when the speed is known | ||
560 | */ | ||
561 | ret = bdc_ep_enable(bdc->bdc_ep_array[1]); | ||
562 | if (ret) { | ||
563 | dev_err(bdc->dev, "fail to enable %s\n", | ||
564 | bdc->bdc_ep_array[1]->name); | ||
565 | goto err1; | ||
566 | } | ||
567 | INIT_DELAYED_WORK(&bdc->func_wake_notify, bdc_func_wake_timer); | ||
568 | /* Enable Interrupts */ | ||
569 | temp = bdc_readl(bdc->regs, BDC_BDCSC); | ||
570 | temp |= BDC_GIE; | ||
571 | bdc_writel(bdc->regs, BDC_BDCSC, temp); | ||
572 | return 0; | ||
573 | err1: | ||
574 | usb_del_gadget_udc(&bdc->gadget); | ||
575 | err0: | ||
576 | bdc_free_ep(bdc); | ||
577 | |||
578 | return ret; | ||
579 | } | ||
580 | |||
581 | void bdc_udc_exit(struct bdc *bdc) | ||
582 | { | ||
583 | dev_dbg(bdc->dev, "%s()\n", __func__); | ||
584 | bdc_ep_disable(bdc->bdc_ep_array[1]); | ||
585 | usb_del_gadget_udc(&bdc->gadget); | ||
586 | bdc_free_ep(bdc); | ||
587 | } | ||
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 81dc5959e36b..1c69c760408e 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c | |||
@@ -367,19 +367,22 @@ static void set_link_state(struct dummy_hcd *dum_hcd) | |||
367 | dum_hcd->active) | 367 | dum_hcd->active) |
368 | dum_hcd->resuming = 0; | 368 | dum_hcd->resuming = 0; |
369 | 369 | ||
370 | /* if !connected or reset */ | 370 | /* Currently !connected or in reset */ |
371 | if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || | 371 | if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || |
372 | (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { | 372 | (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { |
373 | /* | 373 | unsigned disconnect = USB_PORT_STAT_CONNECTION & |
374 | * We're connected and not reset (reset occurred now), | 374 | dum_hcd->old_status & (~dum_hcd->port_status); |
375 | * and driver attached - disconnect! | 375 | unsigned reset = USB_PORT_STAT_RESET & |
376 | */ | 376 | (~dum_hcd->old_status) & dum_hcd->port_status; |
377 | if ((dum_hcd->old_status & USB_PORT_STAT_CONNECTION) != 0 && | 377 | |
378 | (dum_hcd->old_status & USB_PORT_STAT_RESET) == 0 && | 378 | /* Report reset and disconnect events to the driver */ |
379 | dum->driver) { | 379 | if (dum->driver && (disconnect || reset)) { |
380 | stop_activity(dum); | 380 | stop_activity(dum); |
381 | spin_unlock(&dum->lock); | 381 | spin_unlock(&dum->lock); |
382 | dum->driver->disconnect(&dum->gadget); | 382 | if (reset) |
383 | usb_gadget_udc_reset(&dum->gadget, dum->driver); | ||
384 | else | ||
385 | dum->driver->disconnect(&dum->gadget); | ||
383 | spin_lock(&dum->lock); | 386 | spin_lock(&dum->lock); |
384 | } | 387 | } |
385 | } else if (dum_hcd->active != dum_hcd->old_active) { | 388 | } else if (dum_hcd->active != dum_hcd->old_active) { |
@@ -851,8 +854,7 @@ static int dummy_pullup(struct usb_gadget *_gadget, int value) | |||
851 | 854 | ||
852 | static int dummy_udc_start(struct usb_gadget *g, | 855 | static int dummy_udc_start(struct usb_gadget *g, |
853 | struct usb_gadget_driver *driver); | 856 | struct usb_gadget_driver *driver); |
854 | static int dummy_udc_stop(struct usb_gadget *g, | 857 | static int dummy_udc_stop(struct usb_gadget *g); |
855 | struct usb_gadget_driver *driver); | ||
856 | 858 | ||
857 | static const struct usb_gadget_ops dummy_ops = { | 859 | static const struct usb_gadget_ops dummy_ops = { |
858 | .get_frame = dummy_g_get_frame, | 860 | .get_frame = dummy_g_get_frame, |
@@ -908,23 +910,16 @@ static int dummy_udc_start(struct usb_gadget *g, | |||
908 | */ | 910 | */ |
909 | 911 | ||
910 | dum->devstatus = 0; | 912 | dum->devstatus = 0; |
911 | |||
912 | dum->driver = driver; | 913 | dum->driver = driver; |
913 | dev_dbg(udc_dev(dum), "binding gadget driver '%s'\n", | 914 | |
914 | driver->driver.name); | ||
915 | return 0; | 915 | return 0; |
916 | } | 916 | } |
917 | 917 | ||
918 | static int dummy_udc_stop(struct usb_gadget *g, | 918 | static int dummy_udc_stop(struct usb_gadget *g) |
919 | struct usb_gadget_driver *driver) | ||
920 | { | 919 | { |
921 | struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); | 920 | struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); |
922 | struct dummy *dum = dum_hcd->dum; | 921 | struct dummy *dum = dum_hcd->dum; |
923 | 922 | ||
924 | if (driver) | ||
925 | dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", | ||
926 | driver->driver.name); | ||
927 | |||
928 | dum->driver = NULL; | 923 | dum->driver = NULL; |
929 | 924 | ||
930 | return 0; | 925 | return 0; |
@@ -2370,7 +2365,6 @@ static void dummy_stop(struct usb_hcd *hcd) | |||
2370 | 2365 | ||
2371 | dum = hcd_to_dummy_hcd(hcd)->dum; | 2366 | dum = hcd_to_dummy_hcd(hcd)->dum; |
2372 | device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs); | 2367 | device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs); |
2373 | usb_gadget_unregister_driver(dum->driver); | ||
2374 | dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n"); | 2368 | dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n"); |
2375 | } | 2369 | } |
2376 | 2370 | ||
diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c index 1d315921bf34..1ca52e11eb98 100644 --- a/drivers/usb/gadget/udc/fotg210-udc.c +++ b/drivers/usb/gadget/udc/fotg210-udc.c | |||
@@ -1053,8 +1053,7 @@ static void fotg210_init(struct fotg210_udc *fotg210) | |||
1053 | iowrite32(value, fotg210->reg + FOTG210_DMISGR0); | 1053 | iowrite32(value, fotg210->reg + FOTG210_DMISGR0); |
1054 | } | 1054 | } |
1055 | 1055 | ||
1056 | static int fotg210_udc_stop(struct usb_gadget *g, | 1056 | static int fotg210_udc_stop(struct usb_gadget *g) |
1057 | struct usb_gadget_driver *driver) | ||
1058 | { | 1057 | { |
1059 | struct fotg210_udc *fotg210 = gadget_to_fotg210(g); | 1058 | struct fotg210_udc *fotg210 = gadget_to_fotg210(g); |
1060 | unsigned long flags; | 1059 | unsigned long flags; |
diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index dd18ea38e391..d201f9a89ce3 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c | |||
@@ -1887,8 +1887,7 @@ static int qe_get_frame(struct usb_gadget *gadget) | |||
1887 | 1887 | ||
1888 | static int fsl_qe_start(struct usb_gadget *gadget, | 1888 | static int fsl_qe_start(struct usb_gadget *gadget, |
1889 | struct usb_gadget_driver *driver); | 1889 | struct usb_gadget_driver *driver); |
1890 | static int fsl_qe_stop(struct usb_gadget *gadget, | 1890 | static int fsl_qe_stop(struct usb_gadget *gadget); |
1891 | struct usb_gadget_driver *driver); | ||
1892 | 1891 | ||
1893 | /* defined in usb_gadget.h */ | 1892 | /* defined in usb_gadget.h */ |
1894 | static const struct usb_gadget_ops qe_gadget_ops = { | 1893 | static const struct usb_gadget_ops qe_gadget_ops = { |
@@ -1918,7 +1917,7 @@ static int reset_queues(struct qe_udc *udc) | |||
1918 | 1917 | ||
1919 | /* report disconnect; the driver is already quiesced */ | 1918 | /* report disconnect; the driver is already quiesced */ |
1920 | spin_unlock(&udc->lock); | 1919 | spin_unlock(&udc->lock); |
1921 | udc->driver->disconnect(&udc->gadget); | 1920 | usb_gadget_udc_reset(&udc->gadget, udc->driver); |
1922 | spin_lock(&udc->lock); | 1921 | spin_lock(&udc->lock); |
1923 | 1922 | ||
1924 | return 0; | 1923 | return 0; |
@@ -2305,13 +2304,10 @@ static int fsl_qe_start(struct usb_gadget *gadget, | |||
2305 | udc->ep0_dir = USB_DIR_OUT; | 2304 | udc->ep0_dir = USB_DIR_OUT; |
2306 | spin_unlock_irqrestore(&udc->lock, flags); | 2305 | spin_unlock_irqrestore(&udc->lock, flags); |
2307 | 2306 | ||
2308 | dev_info(udc->dev, "%s bind to driver %s\n", udc->gadget.name, | ||
2309 | driver->driver.name); | ||
2310 | return 0; | 2307 | return 0; |
2311 | } | 2308 | } |
2312 | 2309 | ||
2313 | static int fsl_qe_stop(struct usb_gadget *gadget, | 2310 | static int fsl_qe_stop(struct usb_gadget *gadget) |
2314 | struct usb_gadget_driver *driver) | ||
2315 | { | 2311 | { |
2316 | struct qe_udc *udc; | 2312 | struct qe_udc *udc; |
2317 | struct qe_ep *loop_ep; | 2313 | struct qe_ep *loop_ep; |
@@ -2336,8 +2332,6 @@ static int fsl_qe_stop(struct usb_gadget *gadget, | |||
2336 | 2332 | ||
2337 | udc->driver = NULL; | 2333 | udc->driver = NULL; |
2338 | 2334 | ||
2339 | dev_info(udc->dev, "unregistered gadget driver '%s'\r\n", | ||
2340 | driver->driver.name); | ||
2341 | return 0; | 2335 | return 0; |
2342 | } | 2336 | } |
2343 | 2337 | ||
@@ -2538,7 +2532,6 @@ static int qe_udc_probe(struct platform_device *ofdev) | |||
2538 | /* create a buf for ZLP send, need to remain zeroed */ | 2532 | /* create a buf for ZLP send, need to remain zeroed */ |
2539 | udc->nullbuf = devm_kzalloc(&ofdev->dev, 256, GFP_KERNEL); | 2533 | udc->nullbuf = devm_kzalloc(&ofdev->dev, 256, GFP_KERNEL); |
2540 | if (udc->nullbuf == NULL) { | 2534 | if (udc->nullbuf == NULL) { |
2541 | dev_err(udc->dev, "cannot alloc nullbuf\n"); | ||
2542 | ret = -ENOMEM; | 2535 | ret = -ENOMEM; |
2543 | goto err3; | 2536 | goto err3; |
2544 | } | 2537 | } |
diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index c3620791a315..f340181da23c 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c | |||
@@ -1236,9 +1236,8 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) | |||
1236 | 1236 | ||
1237 | static int fsl_udc_start(struct usb_gadget *g, | 1237 | static int fsl_udc_start(struct usb_gadget *g, |
1238 | struct usb_gadget_driver *driver); | 1238 | struct usb_gadget_driver *driver); |
1239 | static int fsl_udc_stop(struct usb_gadget *g, | 1239 | static int fsl_udc_stop(struct usb_gadget *g); |
1240 | struct usb_gadget_driver *driver); | 1240 | |
1241 | /* defined in gadget.h */ | ||
1242 | static const struct usb_gadget_ops fsl_gadget_ops = { | 1241 | static const struct usb_gadget_ops fsl_gadget_ops = { |
1243 | .get_frame = fsl_get_frame, | 1242 | .get_frame = fsl_get_frame, |
1244 | .wakeup = fsl_wakeup, | 1243 | .wakeup = fsl_wakeup, |
@@ -1772,7 +1771,7 @@ static void bus_resume(struct fsl_udc *udc) | |||
1772 | } | 1771 | } |
1773 | 1772 | ||
1774 | /* Clear up all ep queues */ | 1773 | /* Clear up all ep queues */ |
1775 | static int reset_queues(struct fsl_udc *udc) | 1774 | static int reset_queues(struct fsl_udc *udc, bool bus_reset) |
1776 | { | 1775 | { |
1777 | u8 pipe; | 1776 | u8 pipe; |
1778 | 1777 | ||
@@ -1781,7 +1780,10 @@ static int reset_queues(struct fsl_udc *udc) | |||
1781 | 1780 | ||
1782 | /* report disconnect; the driver is already quiesced */ | 1781 | /* report disconnect; the driver is already quiesced */ |
1783 | spin_unlock(&udc->lock); | 1782 | spin_unlock(&udc->lock); |
1784 | udc->driver->disconnect(&udc->gadget); | 1783 | if (bus_reset) |
1784 | usb_gadget_udc_reset(&udc->gadget, udc->driver); | ||
1785 | else | ||
1786 | udc->driver->disconnect(&udc->gadget); | ||
1785 | spin_lock(&udc->lock); | 1787 | spin_lock(&udc->lock); |
1786 | 1788 | ||
1787 | return 0; | 1789 | return 0; |
@@ -1835,7 +1837,7 @@ static void reset_irq(struct fsl_udc *udc) | |||
1835 | udc->bus_reset = 1; | 1837 | udc->bus_reset = 1; |
1836 | /* Reset all the queues, include XD, dTD, EP queue | 1838 | /* Reset all the queues, include XD, dTD, EP queue |
1837 | * head and TR Queue */ | 1839 | * head and TR Queue */ |
1838 | reset_queues(udc); | 1840 | reset_queues(udc, true); |
1839 | udc->usb_state = USB_STATE_DEFAULT; | 1841 | udc->usb_state = USB_STATE_DEFAULT; |
1840 | } else { | 1842 | } else { |
1841 | VDBG("Controller reset"); | 1843 | VDBG("Controller reset"); |
@@ -1844,7 +1846,7 @@ static void reset_irq(struct fsl_udc *udc) | |||
1844 | dr_controller_setup(udc); | 1846 | dr_controller_setup(udc); |
1845 | 1847 | ||
1846 | /* Reset all internal used Queues */ | 1848 | /* Reset all internal used Queues */ |
1847 | reset_queues(udc); | 1849 | reset_queues(udc, false); |
1848 | 1850 | ||
1849 | ep0_setup(udc); | 1851 | ep0_setup(udc); |
1850 | 1852 | ||
@@ -1975,8 +1977,7 @@ static int fsl_udc_start(struct usb_gadget *g, | |||
1975 | } | 1977 | } |
1976 | 1978 | ||
1977 | /* Disconnect from gadget driver */ | 1979 | /* Disconnect from gadget driver */ |
1978 | static int fsl_udc_stop(struct usb_gadget *g, | 1980 | static int fsl_udc_stop(struct usb_gadget *g) |
1979 | struct usb_gadget_driver *driver) | ||
1980 | { | 1981 | { |
1981 | struct fsl_ep *loop_ep; | 1982 | struct fsl_ep *loop_ep; |
1982 | unsigned long flags; | 1983 | unsigned long flags; |
diff --git a/drivers/usb/gadget/udc/fusb300_udc.c b/drivers/usb/gadget/udc/fusb300_udc.c index 8286df72add4..a1b33f534b52 100644 --- a/drivers/usb/gadget/udc/fusb300_udc.c +++ b/drivers/usb/gadget/udc/fusb300_udc.c | |||
@@ -1320,8 +1320,7 @@ static int fusb300_udc_start(struct usb_gadget *g, | |||
1320 | return 0; | 1320 | return 0; |
1321 | } | 1321 | } |
1322 | 1322 | ||
1323 | static int fusb300_udc_stop(struct usb_gadget *g, | 1323 | static int fusb300_udc_stop(struct usb_gadget *g) |
1324 | struct usb_gadget_driver *driver) | ||
1325 | { | 1324 | { |
1326 | struct fusb300 *fusb300 = to_fusb300(g); | 1325 | struct fusb300 *fusb300 = to_fusb300(g); |
1327 | 1326 | ||
diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c index bf9c5ef8b56b..5b9176e7202a 100644 --- a/drivers/usb/gadget/udc/goku_udc.c +++ b/drivers/usb/gadget/udc/goku_udc.c | |||
@@ -992,8 +992,7 @@ static int goku_get_frame(struct usb_gadget *_gadget) | |||
992 | 992 | ||
993 | static int goku_udc_start(struct usb_gadget *g, | 993 | static int goku_udc_start(struct usb_gadget *g, |
994 | struct usb_gadget_driver *driver); | 994 | struct usb_gadget_driver *driver); |
995 | static int goku_udc_stop(struct usb_gadget *g, | 995 | static int goku_udc_stop(struct usb_gadget *g); |
996 | struct usb_gadget_driver *driver); | ||
997 | 996 | ||
998 | static const struct usb_gadget_ops goku_ops = { | 997 | static const struct usb_gadget_ops goku_ops = { |
999 | .get_frame = goku_get_frame, | 998 | .get_frame = goku_get_frame, |
@@ -1364,8 +1363,7 @@ static void stop_activity(struct goku_udc *dev) | |||
1364 | udc_enable(dev); | 1363 | udc_enable(dev); |
1365 | } | 1364 | } |
1366 | 1365 | ||
1367 | static int goku_udc_stop(struct usb_gadget *g, | 1366 | static int goku_udc_stop(struct usb_gadget *g) |
1368 | struct usb_gadget_driver *driver) | ||
1369 | { | 1367 | { |
1370 | struct goku_udc *dev = to_goku_udc(g); | 1368 | struct goku_udc *dev = to_goku_udc(g); |
1371 | unsigned long flags; | 1369 | unsigned long flags; |
diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index 1b3048a6a2a3..320df9a250ff 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c | |||
@@ -1932,14 +1932,10 @@ static int gr_udc_start(struct usb_gadget *gadget, | |||
1932 | 1932 | ||
1933 | spin_unlock(&dev->lock); | 1933 | spin_unlock(&dev->lock); |
1934 | 1934 | ||
1935 | dev_info(dev->dev, "Started with gadget driver '%s'\n", | ||
1936 | driver->driver.name); | ||
1937 | |||
1938 | return 0; | 1935 | return 0; |
1939 | } | 1936 | } |
1940 | 1937 | ||
1941 | static int gr_udc_stop(struct usb_gadget *gadget, | 1938 | static int gr_udc_stop(struct usb_gadget *gadget) |
1942 | struct usb_gadget_driver *driver) | ||
1943 | { | 1939 | { |
1944 | struct gr_udc *dev = to_gr_udc(gadget); | 1940 | struct gr_udc *dev = to_gr_udc(gadget); |
1945 | unsigned long flags; | 1941 | unsigned long flags; |
@@ -1951,8 +1947,6 @@ static int gr_udc_stop(struct usb_gadget *gadget, | |||
1951 | 1947 | ||
1952 | spin_unlock_irqrestore(&dev->lock, flags); | 1948 | spin_unlock_irqrestore(&dev->lock, flags); |
1953 | 1949 | ||
1954 | dev_info(dev->dev, "Stopped\n"); | ||
1955 | |||
1956 | return 0; | 1950 | return 0; |
1957 | } | 1951 | } |
1958 | 1952 | ||
diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index feab0bac8fdc..976529631c19 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c | |||
@@ -582,8 +582,7 @@ static void create_debug_file(struct lpc32xx_udc *udc) | |||
582 | 582 | ||
583 | static void remove_debug_file(struct lpc32xx_udc *udc) | 583 | static void remove_debug_file(struct lpc32xx_udc *udc) |
584 | { | 584 | { |
585 | if (udc->pde) | 585 | debugfs_remove(udc->pde); |
586 | debugfs_remove(udc->pde); | ||
587 | } | 586 | } |
588 | 587 | ||
589 | #else | 588 | #else |
@@ -2559,7 +2558,7 @@ static int lpc32xx_pullup(struct usb_gadget *gadget, int is_on) | |||
2559 | } | 2558 | } |
2560 | 2559 | ||
2561 | static int lpc32xx_start(struct usb_gadget *, struct usb_gadget_driver *); | 2560 | static int lpc32xx_start(struct usb_gadget *, struct usb_gadget_driver *); |
2562 | static int lpc32xx_stop(struct usb_gadget *, struct usb_gadget_driver *); | 2561 | static int lpc32xx_stop(struct usb_gadget *); |
2563 | 2562 | ||
2564 | static const struct usb_gadget_ops lpc32xx_udc_ops = { | 2563 | static const struct usb_gadget_ops lpc32xx_udc_ops = { |
2565 | .get_frame = lpc32xx_get_frame, | 2564 | .get_frame = lpc32xx_get_frame, |
@@ -2961,15 +2960,11 @@ static int lpc32xx_start(struct usb_gadget *gadget, | |||
2961 | return 0; | 2960 | return 0; |
2962 | } | 2961 | } |
2963 | 2962 | ||
2964 | static int lpc32xx_stop(struct usb_gadget *gadget, | 2963 | static int lpc32xx_stop(struct usb_gadget *gadget) |
2965 | struct usb_gadget_driver *driver) | ||
2966 | { | 2964 | { |
2967 | int i; | 2965 | int i; |
2968 | struct lpc32xx_udc *udc = to_udc(gadget); | 2966 | struct lpc32xx_udc *udc = to_udc(gadget); |
2969 | 2967 | ||
2970 | if (!driver || driver != udc->driver) | ||
2971 | return -EINVAL; | ||
2972 | |||
2973 | for (i = IRQ_USB_LP; i <= IRQ_USB_ATX; i++) | 2968 | for (i = IRQ_USB_LP; i <= IRQ_USB_ATX; i++) |
2974 | disable_irq(udc->udp_irq[i]); | 2969 | disable_irq(udc->udp_irq[i]); |
2975 | 2970 | ||
diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c index 898565687a8c..ef3f73dd9099 100644 --- a/drivers/usb/gadget/udc/m66592-udc.c +++ b/drivers/usb/gadget/udc/m66592-udc.c | |||
@@ -1142,7 +1142,7 @@ static void irq_device_state(struct m66592 *m66592) | |||
1142 | m66592_write(m66592, ~M66592_DVST, M66592_INTSTS0); | 1142 | m66592_write(m66592, ~M66592_DVST, M66592_INTSTS0); |
1143 | 1143 | ||
1144 | if (dvsq == M66592_DS_DFLT) { /* bus reset */ | 1144 | if (dvsq == M66592_DS_DFLT) { /* bus reset */ |
1145 | m66592->driver->disconnect(&m66592->gadget); | 1145 | usb_gadget_udc_reset(&m66592->gadget, m66592->driver); |
1146 | m66592_update_usb_speed(m66592); | 1146 | m66592_update_usb_speed(m66592); |
1147 | } | 1147 | } |
1148 | if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG) | 1148 | if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG) |
@@ -1485,8 +1485,7 @@ static int m66592_udc_start(struct usb_gadget *g, | |||
1485 | return 0; | 1485 | return 0; |
1486 | } | 1486 | } |
1487 | 1487 | ||
1488 | static int m66592_udc_stop(struct usb_gadget *g, | 1488 | static int m66592_udc_stop(struct usb_gadget *g) |
1489 | struct usb_gadget_driver *driver) | ||
1490 | { | 1489 | { |
1491 | struct m66592 *m66592 = to_m66592(g); | 1490 | struct m66592 *m66592 = to_m66592(g); |
1492 | 1491 | ||
diff --git a/drivers/usb/gadget/udc/mv_u3d_core.c b/drivers/usb/gadget/udc/mv_u3d_core.c index 046a1f808b0d..ea422ac79990 100644 --- a/drivers/usb/gadget/udc/mv_u3d_core.c +++ b/drivers/usb/gadget/udc/mv_u3d_core.c | |||
@@ -1266,8 +1266,7 @@ static int mv_u3d_start(struct usb_gadget *g, | |||
1266 | return 0; | 1266 | return 0; |
1267 | } | 1267 | } |
1268 | 1268 | ||
1269 | static int mv_u3d_stop(struct usb_gadget *g, | 1269 | static int mv_u3d_stop(struct usb_gadget *g) |
1270 | struct usb_gadget_driver *driver) | ||
1271 | { | 1270 | { |
1272 | struct mv_u3d *u3d = container_of(g, struct mv_u3d, gadget); | 1271 | struct mv_u3d *u3d = container_of(g, struct mv_u3d, gadget); |
1273 | struct mv_usb_platform_data *pdata = dev_get_platdata(u3d->dev); | 1272 | struct mv_usb_platform_data *pdata = dev_get_platdata(u3d->dev); |
@@ -1284,7 +1283,7 @@ static int mv_u3d_stop(struct usb_gadget *g, | |||
1284 | mv_u3d_controller_stop(u3d); | 1283 | mv_u3d_controller_stop(u3d); |
1285 | /* stop all usb activities */ | 1284 | /* stop all usb activities */ |
1286 | u3d->gadget.speed = USB_SPEED_UNKNOWN; | 1285 | u3d->gadget.speed = USB_SPEED_UNKNOWN; |
1287 | mv_u3d_stop_activity(u3d, driver); | 1286 | mv_u3d_stop_activity(u3d, NULL); |
1288 | mv_u3d_disable(u3d); | 1287 | mv_u3d_disable(u3d); |
1289 | 1288 | ||
1290 | if (pdata->phy_deinit) | 1289 | if (pdata->phy_deinit) |
diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index 3c5db80ae325..d4edd763e963 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c | |||
@@ -1223,7 +1223,7 @@ static int mv_udc_pullup(struct usb_gadget *gadget, int is_on) | |||
1223 | } | 1223 | } |
1224 | 1224 | ||
1225 | static int mv_udc_start(struct usb_gadget *, struct usb_gadget_driver *); | 1225 | static int mv_udc_start(struct usb_gadget *, struct usb_gadget_driver *); |
1226 | static int mv_udc_stop(struct usb_gadget *, struct usb_gadget_driver *); | 1226 | static int mv_udc_stop(struct usb_gadget *); |
1227 | /* device controller usb_gadget_ops structure */ | 1227 | /* device controller usb_gadget_ops structure */ |
1228 | static const struct usb_gadget_ops mv_ops = { | 1228 | static const struct usb_gadget_ops mv_ops = { |
1229 | 1229 | ||
@@ -1307,6 +1307,23 @@ static void nuke(struct mv_ep *ep, int status) | |||
1307 | } | 1307 | } |
1308 | } | 1308 | } |
1309 | 1309 | ||
1310 | static void gadget_reset(struct mv_udc *udc, struct usb_gadget_driver *driver) | ||
1311 | { | ||
1312 | struct mv_ep *ep; | ||
1313 | |||
1314 | nuke(&udc->eps[0], -ESHUTDOWN); | ||
1315 | |||
1316 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { | ||
1317 | nuke(ep, -ESHUTDOWN); | ||
1318 | } | ||
1319 | |||
1320 | /* report reset; the driver is already quiesced */ | ||
1321 | if (driver) { | ||
1322 | spin_unlock(&udc->lock); | ||
1323 | usb_gadget_udc_reset(&udc->gadget, driver); | ||
1324 | spin_lock(&udc->lock); | ||
1325 | } | ||
1326 | } | ||
1310 | /* stop all USB activities */ | 1327 | /* stop all USB activities */ |
1311 | static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver) | 1328 | static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver) |
1312 | { | 1329 | { |
@@ -1371,8 +1388,7 @@ static int mv_udc_start(struct usb_gadget *gadget, | |||
1371 | return 0; | 1388 | return 0; |
1372 | } | 1389 | } |
1373 | 1390 | ||
1374 | static int mv_udc_stop(struct usb_gadget *gadget, | 1391 | static int mv_udc_stop(struct usb_gadget *gadget) |
1375 | struct usb_gadget_driver *driver) | ||
1376 | { | 1392 | { |
1377 | struct mv_udc *udc; | 1393 | struct mv_udc *udc; |
1378 | unsigned long flags; | 1394 | unsigned long flags; |
@@ -1386,7 +1402,7 @@ static int mv_udc_stop(struct usb_gadget *gadget, | |||
1386 | 1402 | ||
1387 | /* stop all usb activities */ | 1403 | /* stop all usb activities */ |
1388 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1404 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1389 | stop_activity(udc, driver); | 1405 | stop_activity(udc, NULL); |
1390 | mv_udc_disable(udc); | 1406 | mv_udc_disable(udc); |
1391 | 1407 | ||
1392 | spin_unlock_irqrestore(&udc->lock, flags); | 1408 | spin_unlock_irqrestore(&udc->lock, flags); |
@@ -1882,7 +1898,7 @@ static void irq_process_reset(struct mv_udc *udc) | |||
1882 | dev_info(&udc->dev->dev, "usb bus reset\n"); | 1898 | dev_info(&udc->dev->dev, "usb bus reset\n"); |
1883 | udc->usb_state = USB_STATE_DEFAULT; | 1899 | udc->usb_state = USB_STATE_DEFAULT; |
1884 | /* reset all the queues, stop all USB activities */ | 1900 | /* reset all the queues, stop all USB activities */ |
1885 | stop_activity(udc, udc->driver); | 1901 | gadget_reset(udc, udc->driver); |
1886 | } else { | 1902 | } else { |
1887 | dev_info(&udc->dev->dev, "USB reset portsc 0x%x\n", | 1903 | dev_info(&udc->dev->dev, "USB reset portsc 0x%x\n", |
1888 | readl(&udc->op_regs->portsc)); | 1904 | readl(&udc->op_regs->portsc)); |
@@ -2107,10 +2123,8 @@ static int mv_udc_probe(struct platform_device *pdev) | |||
2107 | } | 2123 | } |
2108 | 2124 | ||
2109 | udc = devm_kzalloc(&pdev->dev, sizeof(*udc), GFP_KERNEL); | 2125 | udc = devm_kzalloc(&pdev->dev, sizeof(*udc), GFP_KERNEL); |
2110 | if (udc == NULL) { | 2126 | if (udc == NULL) |
2111 | dev_err(&pdev->dev, "failed to allocate memory for udc\n"); | ||
2112 | return -ENOMEM; | 2127 | return -ENOMEM; |
2113 | } | ||
2114 | 2128 | ||
2115 | udc->done = &release_done; | 2129 | udc->done = &release_done; |
2116 | udc->pdata = dev_get_platdata(&pdev->dev); | 2130 | udc->pdata = dev_get_platdata(&pdev->dev); |
@@ -2207,7 +2221,6 @@ static int mv_udc_probe(struct platform_device *pdev) | |||
2207 | size = udc->max_eps * sizeof(struct mv_ep) *2; | 2221 | size = udc->max_eps * sizeof(struct mv_ep) *2; |
2208 | udc->eps = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | 2222 | udc->eps = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); |
2209 | if (udc->eps == NULL) { | 2223 | if (udc->eps == NULL) { |
2210 | dev_err(&pdev->dev, "allocate ep memory failed\n"); | ||
2211 | retval = -ENOMEM; | 2224 | retval = -ENOMEM; |
2212 | goto err_destroy_dma; | 2225 | goto err_destroy_dma; |
2213 | } | 2226 | } |
@@ -2216,7 +2229,6 @@ static int mv_udc_probe(struct platform_device *pdev) | |||
2216 | udc->status_req = devm_kzalloc(&pdev->dev, sizeof(struct mv_req), | 2229 | udc->status_req = devm_kzalloc(&pdev->dev, sizeof(struct mv_req), |
2217 | GFP_KERNEL); | 2230 | GFP_KERNEL); |
2218 | if (!udc->status_req) { | 2231 | if (!udc->status_req) { |
2219 | dev_err(&pdev->dev, "allocate status_req memory failed\n"); | ||
2220 | retval = -ENOMEM; | 2232 | retval = -ENOMEM; |
2221 | goto err_destroy_dma; | 2233 | goto err_destroy_dma; |
2222 | } | 2234 | } |
diff --git a/drivers/usb/gadget/udc/net2272.c b/drivers/usb/gadget/udc/net2272.c index 84d7162a8022..3a90856625f2 100644 --- a/drivers/usb/gadget/udc/net2272.c +++ b/drivers/usb/gadget/udc/net2272.c | |||
@@ -1169,8 +1169,7 @@ net2272_pullup(struct usb_gadget *_gadget, int is_on) | |||
1169 | 1169 | ||
1170 | static int net2272_start(struct usb_gadget *_gadget, | 1170 | static int net2272_start(struct usb_gadget *_gadget, |
1171 | struct usb_gadget_driver *driver); | 1171 | struct usb_gadget_driver *driver); |
1172 | static int net2272_stop(struct usb_gadget *_gadget, | 1172 | static int net2272_stop(struct usb_gadget *_gadget); |
1173 | struct usb_gadget_driver *driver); | ||
1174 | 1173 | ||
1175 | static const struct usb_gadget_ops net2272_ops = { | 1174 | static const struct usb_gadget_ops net2272_ops = { |
1176 | .get_frame = net2272_get_frame, | 1175 | .get_frame = net2272_get_frame, |
@@ -1471,8 +1470,6 @@ static int net2272_start(struct usb_gadget *_gadget, | |||
1471 | */ | 1470 | */ |
1472 | net2272_ep0_start(dev); | 1471 | net2272_ep0_start(dev); |
1473 | 1472 | ||
1474 | dev_dbg(dev->dev, "%s ready\n", driver->driver.name); | ||
1475 | |||
1476 | return 0; | 1473 | return 0; |
1477 | } | 1474 | } |
1478 | 1475 | ||
@@ -1502,8 +1499,7 @@ stop_activity(struct net2272 *dev, struct usb_gadget_driver *driver) | |||
1502 | net2272_usb_reinit(dev); | 1499 | net2272_usb_reinit(dev); |
1503 | } | 1500 | } |
1504 | 1501 | ||
1505 | static int net2272_stop(struct usb_gadget *_gadget, | 1502 | static int net2272_stop(struct usb_gadget *_gadget) |
1506 | struct usb_gadget_driver *driver) | ||
1507 | { | 1503 | { |
1508 | struct net2272 *dev; | 1504 | struct net2272 *dev; |
1509 | unsigned long flags; | 1505 | unsigned long flags; |
@@ -1511,12 +1507,11 @@ static int net2272_stop(struct usb_gadget *_gadget, | |||
1511 | dev = container_of(_gadget, struct net2272, gadget); | 1507 | dev = container_of(_gadget, struct net2272, gadget); |
1512 | 1508 | ||
1513 | spin_lock_irqsave(&dev->lock, flags); | 1509 | spin_lock_irqsave(&dev->lock, flags); |
1514 | stop_activity(dev, driver); | 1510 | stop_activity(dev, NULL); |
1515 | spin_unlock_irqrestore(&dev->lock, flags); | 1511 | spin_unlock_irqrestore(&dev->lock, flags); |
1516 | 1512 | ||
1517 | dev->driver = NULL; | 1513 | dev->driver = NULL; |
1518 | 1514 | ||
1519 | dev_dbg(dev->dev, "unregistered driver '%s'\n", driver->driver.name); | ||
1520 | return 0; | 1515 | return 0; |
1521 | } | 1516 | } |
1522 | 1517 | ||
@@ -1987,17 +1982,42 @@ net2272_handle_stat1_irqs(struct net2272 *dev, u8 stat) | |||
1987 | mask = (1 << USB_HIGH_SPEED) | (1 << USB_FULL_SPEED); | 1982 | mask = (1 << USB_HIGH_SPEED) | (1 << USB_FULL_SPEED); |
1988 | 1983 | ||
1989 | if (stat & tmp) { | 1984 | if (stat & tmp) { |
1985 | bool reset = false; | ||
1986 | bool disconnect = false; | ||
1987 | |||
1988 | /* | ||
1989 | * Ignore disconnects and resets if the speed hasn't been set. | ||
1990 | * VBUS can bounce and there's always an initial reset. | ||
1991 | */ | ||
1990 | net2272_write(dev, IRQSTAT1, tmp); | 1992 | net2272_write(dev, IRQSTAT1, tmp); |
1991 | if ((((stat & (1 << ROOT_PORT_RESET_INTERRUPT)) && | 1993 | if (dev->gadget.speed != USB_SPEED_UNKNOWN) { |
1992 | ((net2272_read(dev, USBCTL1) & mask) == 0)) | 1994 | if ((stat & (1 << VBUS_INTERRUPT)) && |
1993 | || ((net2272_read(dev, USBCTL1) & (1 << VBUS_PIN)) | 1995 | (net2272_read(dev, USBCTL1) & |
1994 | == 0)) | 1996 | (1 << VBUS_PIN)) == 0) { |
1995 | && (dev->gadget.speed != USB_SPEED_UNKNOWN)) { | 1997 | disconnect = true; |
1996 | dev_dbg(dev->dev, "disconnect %s\n", | 1998 | dev_dbg(dev->dev, "disconnect %s\n", |
1997 | dev->driver->driver.name); | 1999 | dev->driver->driver.name); |
1998 | stop_activity(dev, dev->driver); | 2000 | } else if ((stat & (1 << ROOT_PORT_RESET_INTERRUPT)) && |
1999 | net2272_ep0_start(dev); | 2001 | (net2272_read(dev, USBCTL1) & mask) |
2000 | return; | 2002 | == 0) { |
2003 | reset = true; | ||
2004 | dev_dbg(dev->dev, "reset %s\n", | ||
2005 | dev->driver->driver.name); | ||
2006 | } | ||
2007 | |||
2008 | if (disconnect || reset) { | ||
2009 | stop_activity(dev, dev->driver); | ||
2010 | net2272_ep0_start(dev); | ||
2011 | spin_unlock(&dev->lock); | ||
2012 | if (reset) | ||
2013 | usb_gadget_udc_reset | ||
2014 | (&dev->gadget, dev->driver); | ||
2015 | else | ||
2016 | (dev->driver->disconnect) | ||
2017 | (&dev->gadget); | ||
2018 | spin_lock(&dev->lock); | ||
2019 | return; | ||
2020 | } | ||
2001 | } | 2021 | } |
2002 | stat &= ~tmp; | 2022 | stat &= ~tmp; |
2003 | 2023 | ||
@@ -2200,18 +2220,8 @@ static void | |||
2200 | net2272_remove(struct net2272 *dev) | 2220 | net2272_remove(struct net2272 *dev) |
2201 | { | 2221 | { |
2202 | usb_del_gadget_udc(&dev->gadget); | 2222 | usb_del_gadget_udc(&dev->gadget); |
2203 | |||
2204 | /* start with the driver above us */ | ||
2205 | if (dev->driver) { | ||
2206 | /* should have been done already by driver model core */ | ||
2207 | dev_warn(dev->dev, "pci remove, driver '%s' is still registered\n", | ||
2208 | dev->driver->driver.name); | ||
2209 | usb_gadget_unregister_driver(dev->driver); | ||
2210 | } | ||
2211 | |||
2212 | free_irq(dev->irq, dev); | 2223 | free_irq(dev->irq, dev); |
2213 | iounmap(dev->base_addr); | 2224 | iounmap(dev->base_addr); |
2214 | |||
2215 | device_remove_file(dev->dev, &dev_attr_registers); | 2225 | device_remove_file(dev->dev, &dev_attr_registers); |
2216 | 2226 | ||
2217 | dev_info(dev->dev, "unbind\n"); | 2227 | dev_info(dev->dev, "unbind\n"); |
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 8d13337e2dde..d6411e0a8e03 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c | |||
@@ -1118,10 +1118,10 @@ static void scan_dma_completions(struct net2280_ep *ep) | |||
1118 | break; | 1118 | break; |
1119 | } else if (!ep->is_in && | 1119 | } else if (!ep->is_in && |
1120 | (req->req.length % ep->ep.maxpacket) != 0) { | 1120 | (req->req.length % ep->ep.maxpacket) != 0) { |
1121 | tmp = readl(&ep->regs->ep_stat); | ||
1122 | if (ep->dev->quirks & PLX_SUPERSPEED) | 1121 | if (ep->dev->quirks & PLX_SUPERSPEED) |
1123 | return dma_done(ep, req, tmp, 0); | 1122 | return dma_done(ep, req, tmp, 0); |
1124 | 1123 | ||
1124 | tmp = readl(&ep->regs->ep_stat); | ||
1125 | /* AVOID TROUBLE HERE by not issuing short reads from | 1125 | /* AVOID TROUBLE HERE by not issuing short reads from |
1126 | * your gadget driver. That helps avoids errata 0121, | 1126 | * your gadget driver. That helps avoids errata 0121, |
1127 | * 0122, and 0124; not all cases trigger the warning. | 1127 | * 0122, and 0124; not all cases trigger the warning. |
@@ -1548,8 +1548,7 @@ static int net2280_pullup(struct usb_gadget *_gadget, int is_on) | |||
1548 | 1548 | ||
1549 | static int net2280_start(struct usb_gadget *_gadget, | 1549 | static int net2280_start(struct usb_gadget *_gadget, |
1550 | struct usb_gadget_driver *driver); | 1550 | struct usb_gadget_driver *driver); |
1551 | static int net2280_stop(struct usb_gadget *_gadget, | 1551 | static int net2280_stop(struct usb_gadget *_gadget); |
1552 | struct usb_gadget_driver *driver); | ||
1553 | 1552 | ||
1554 | static const struct usb_gadget_ops net2280_ops = { | 1553 | static const struct usb_gadget_ops net2280_ops = { |
1555 | .get_frame = net2280_get_frame, | 1554 | .get_frame = net2280_get_frame, |
@@ -2397,11 +2396,6 @@ static int net2280_start(struct usb_gadget *_gadget, | |||
2397 | 2396 | ||
2398 | ep0_start(dev); | 2397 | ep0_start(dev); |
2399 | 2398 | ||
2400 | ep_dbg(dev, "%s ready, usbctl %08x stdrsp %08x\n", | ||
2401 | driver->driver.name, | ||
2402 | readl(&dev->usb->usbctl), | ||
2403 | readl(&dev->usb->stdrsp)); | ||
2404 | |||
2405 | /* pci writes may still be posted */ | 2399 | /* pci writes may still be posted */ |
2406 | return 0; | 2400 | return 0; |
2407 | 2401 | ||
@@ -2437,8 +2431,7 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver) | |||
2437 | usb_reinit(dev); | 2431 | usb_reinit(dev); |
2438 | } | 2432 | } |
2439 | 2433 | ||
2440 | static int net2280_stop(struct usb_gadget *_gadget, | 2434 | static int net2280_stop(struct usb_gadget *_gadget) |
2441 | struct usb_gadget_driver *driver) | ||
2442 | { | 2435 | { |
2443 | struct net2280 *dev; | 2436 | struct net2280 *dev; |
2444 | unsigned long flags; | 2437 | unsigned long flags; |
@@ -2446,11 +2439,9 @@ static int net2280_stop(struct usb_gadget *_gadget, | |||
2446 | dev = container_of(_gadget, struct net2280, gadget); | 2439 | dev = container_of(_gadget, struct net2280, gadget); |
2447 | 2440 | ||
2448 | spin_lock_irqsave(&dev->lock, flags); | 2441 | spin_lock_irqsave(&dev->lock, flags); |
2449 | stop_activity(dev, driver); | 2442 | stop_activity(dev, NULL); |
2450 | spin_unlock_irqrestore(&dev->lock, flags); | 2443 | spin_unlock_irqrestore(&dev->lock, flags); |
2451 | 2444 | ||
2452 | dev->driver = NULL; | ||
2453 | |||
2454 | net2280_led_active(dev, 0); | 2445 | net2280_led_active(dev, 0); |
2455 | 2446 | ||
2456 | /* Disable full-speed test mode */ | 2447 | /* Disable full-speed test mode */ |
@@ -2460,8 +2451,7 @@ static int net2280_stop(struct usb_gadget *_gadget, | |||
2460 | device_remove_file(&dev->pdev->dev, &dev_attr_function); | 2451 | device_remove_file(&dev->pdev->dev, &dev_attr_function); |
2461 | device_remove_file(&dev->pdev->dev, &dev_attr_queues); | 2452 | device_remove_file(&dev->pdev->dev, &dev_attr_queues); |
2462 | 2453 | ||
2463 | ep_dbg(dev, "unregistered driver '%s'\n", | 2454 | dev->driver = NULL; |
2464 | driver ? driver->driver.name : ""); | ||
2465 | 2455 | ||
2466 | return 0; | 2456 | return 0; |
2467 | } | 2457 | } |
@@ -3318,17 +3308,42 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat) | |||
3318 | * only indicates a change in the reset state). | 3308 | * only indicates a change in the reset state). |
3319 | */ | 3309 | */ |
3320 | if (stat & tmp) { | 3310 | if (stat & tmp) { |
3311 | bool reset = false; | ||
3312 | bool disconnect = false; | ||
3313 | |||
3314 | /* | ||
3315 | * Ignore disconnects and resets if the speed hasn't been set. | ||
3316 | * VBUS can bounce and there's always an initial reset. | ||
3317 | */ | ||
3321 | writel(tmp, &dev->regs->irqstat1); | 3318 | writel(tmp, &dev->regs->irqstat1); |
3322 | if ((((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) && | 3319 | if (dev->gadget.speed != USB_SPEED_UNKNOWN) { |
3323 | ((readl(&dev->usb->usbstat) & mask) == 0)) || | 3320 | if ((stat & BIT(VBUS_INTERRUPT)) && |
3324 | ((readl(&dev->usb->usbctl) & | 3321 | (readl(&dev->usb->usbctl) & |
3325 | BIT(VBUS_PIN)) == 0)) && | 3322 | BIT(VBUS_PIN)) == 0) { |
3326 | (dev->gadget.speed != USB_SPEED_UNKNOWN)) { | 3323 | disconnect = true; |
3327 | ep_dbg(dev, "disconnect %s\n", | 3324 | ep_dbg(dev, "disconnect %s\n", |
3328 | dev->driver->driver.name); | 3325 | dev->driver->driver.name); |
3329 | stop_activity(dev, dev->driver); | 3326 | } else if ((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) && |
3330 | ep0_start(dev); | 3327 | (readl(&dev->usb->usbstat) & mask) |
3331 | return; | 3328 | == 0) { |
3329 | reset = true; | ||
3330 | ep_dbg(dev, "reset %s\n", | ||
3331 | dev->driver->driver.name); | ||
3332 | } | ||
3333 | |||
3334 | if (disconnect || reset) { | ||
3335 | stop_activity(dev, dev->driver); | ||
3336 | ep0_start(dev); | ||
3337 | spin_unlock(&dev->lock); | ||
3338 | if (reset) | ||
3339 | usb_gadget_udc_reset | ||
3340 | (&dev->gadget, dev->driver); | ||
3341 | else | ||
3342 | (dev->driver->disconnect) | ||
3343 | (&dev->gadget); | ||
3344 | spin_lock(&dev->lock); | ||
3345 | return; | ||
3346 | } | ||
3332 | } | 3347 | } |
3333 | stat &= ~tmp; | 3348 | stat &= ~tmp; |
3334 | 3349 | ||
diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index dcdfea46003b..534b85c07feb 100644 --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c | |||
@@ -1311,8 +1311,7 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on) | |||
1311 | 1311 | ||
1312 | static int omap_udc_start(struct usb_gadget *g, | 1312 | static int omap_udc_start(struct usb_gadget *g, |
1313 | struct usb_gadget_driver *driver); | 1313 | struct usb_gadget_driver *driver); |
1314 | static int omap_udc_stop(struct usb_gadget *g, | 1314 | static int omap_udc_stop(struct usb_gadget *g); |
1315 | struct usb_gadget_driver *driver); | ||
1316 | 1315 | ||
1317 | static const struct usb_gadget_ops omap_gadget_ops = { | 1316 | static const struct usb_gadget_ops omap_gadget_ops = { |
1318 | .get_frame = omap_get_frame, | 1317 | .get_frame = omap_get_frame, |
@@ -2102,8 +2101,7 @@ done: | |||
2102 | return status; | 2101 | return status; |
2103 | } | 2102 | } |
2104 | 2103 | ||
2105 | static int omap_udc_stop(struct usb_gadget *g, | 2104 | static int omap_udc_stop(struct usb_gadget *g) |
2106 | struct usb_gadget_driver *driver) | ||
2107 | { | 2105 | { |
2108 | unsigned long flags; | 2106 | unsigned long flags; |
2109 | int status = -ENODEV; | 2107 | int status = -ENODEV; |
diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index ccbe3d4a2a50..1c7379ac2379 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c | |||
@@ -1240,8 +1240,8 @@ static int pch_udc_pcd_vbus_draw(struct usb_gadget *gadget, unsigned int mA) | |||
1240 | 1240 | ||
1241 | static int pch_udc_start(struct usb_gadget *g, | 1241 | static int pch_udc_start(struct usb_gadget *g, |
1242 | struct usb_gadget_driver *driver); | 1242 | struct usb_gadget_driver *driver); |
1243 | static int pch_udc_stop(struct usb_gadget *g, | 1243 | static int pch_udc_stop(struct usb_gadget *g); |
1244 | struct usb_gadget_driver *driver); | 1244 | |
1245 | static const struct usb_gadget_ops pch_udc_ops = { | 1245 | static const struct usb_gadget_ops pch_udc_ops = { |
1246 | .get_frame = pch_udc_pcd_get_frame, | 1246 | .get_frame = pch_udc_pcd_get_frame, |
1247 | .wakeup = pch_udc_pcd_wakeup, | 1247 | .wakeup = pch_udc_pcd_wakeup, |
@@ -2592,9 +2592,9 @@ static void pch_udc_svc_ur_interrupt(struct pch_udc_dev *dev) | |||
2592 | /* Complete request queue */ | 2592 | /* Complete request queue */ |
2593 | empty_req_queue(ep); | 2593 | empty_req_queue(ep); |
2594 | } | 2594 | } |
2595 | if (dev->driver && dev->driver->disconnect) { | 2595 | if (dev->driver) { |
2596 | spin_unlock(&dev->lock); | 2596 | spin_unlock(&dev->lock); |
2597 | dev->driver->disconnect(&dev->gadget); | 2597 | usb_gadget_udc_reset(&dev->gadget, dev->driver); |
2598 | spin_lock(&dev->lock); | 2598 | spin_lock(&dev->lock); |
2599 | } | 2599 | } |
2600 | } | 2600 | } |
@@ -3008,8 +3008,7 @@ static int pch_udc_start(struct usb_gadget *g, | |||
3008 | return 0; | 3008 | return 0; |
3009 | } | 3009 | } |
3010 | 3010 | ||
3011 | static int pch_udc_stop(struct usb_gadget *g, | 3011 | static int pch_udc_stop(struct usb_gadget *g) |
3012 | struct usb_gadget_driver *driver) | ||
3013 | { | 3012 | { |
3014 | struct pch_udc_dev *dev = to_pch_udc(g); | 3013 | struct pch_udc_dev *dev = to_pch_udc(g); |
3015 | 3014 | ||
diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index 42f7eeb8ff6f..347a05b5afc1 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c | |||
@@ -998,8 +998,7 @@ static int pxa25x_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | |||
998 | 998 | ||
999 | static int pxa25x_udc_start(struct usb_gadget *g, | 999 | static int pxa25x_udc_start(struct usb_gadget *g, |
1000 | struct usb_gadget_driver *driver); | 1000 | struct usb_gadget_driver *driver); |
1001 | static int pxa25x_udc_stop(struct usb_gadget *g, | 1001 | static int pxa25x_udc_stop(struct usb_gadget *g); |
1002 | struct usb_gadget_driver *driver); | ||
1003 | 1002 | ||
1004 | static const struct usb_gadget_ops pxa25x_udc_ops = { | 1003 | static const struct usb_gadget_ops pxa25x_udc_ops = { |
1005 | .get_frame = pxa25x_udc_get_frame, | 1004 | .get_frame = pxa25x_udc_get_frame, |
@@ -1135,11 +1134,7 @@ static const struct file_operations debug_fops = { | |||
1135 | dev->debugfs_udc = debugfs_create_file(dev->gadget.name, \ | 1134 | dev->debugfs_udc = debugfs_create_file(dev->gadget.name, \ |
1136 | S_IRUGO, NULL, dev, &debug_fops); \ | 1135 | S_IRUGO, NULL, dev, &debug_fops); \ |
1137 | } while (0) | 1136 | } while (0) |
1138 | #define remove_debug_files(dev) \ | 1137 | #define remove_debug_files(dev) debugfs_remove(dev->debugfs_udc) |
1139 | do { \ | ||
1140 | if (dev->debugfs_udc) \ | ||
1141 | debugfs_remove(dev->debugfs_udc); \ | ||
1142 | } while (0) | ||
1143 | 1138 | ||
1144 | #else /* !CONFIG_USB_GADGET_DEBUG_FILES */ | 1139 | #else /* !CONFIG_USB_GADGET_DEBUG_FILES */ |
1145 | 1140 | ||
@@ -1285,6 +1280,33 @@ bind_fail: | |||
1285 | } | 1280 | } |
1286 | 1281 | ||
1287 | static void | 1282 | static void |
1283 | reset_gadget(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) | ||
1284 | { | ||
1285 | int i; | ||
1286 | |||
1287 | /* don't disconnect drivers more than once */ | ||
1288 | if (dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
1289 | driver = NULL; | ||
1290 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
1291 | |||
1292 | /* prevent new request submissions, kill any outstanding requests */ | ||
1293 | for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) { | ||
1294 | struct pxa25x_ep *ep = &dev->ep[i]; | ||
1295 | |||
1296 | ep->stopped = 1; | ||
1297 | nuke(ep, -ESHUTDOWN); | ||
1298 | } | ||
1299 | del_timer_sync(&dev->timer); | ||
1300 | |||
1301 | /* report reset; the driver is already quiesced */ | ||
1302 | if (driver) | ||
1303 | usb_gadget_udc_reset(&dev->gadget, driver); | ||
1304 | |||
1305 | /* re-init driver-visible data structures */ | ||
1306 | udc_reinit(dev); | ||
1307 | } | ||
1308 | |||
1309 | static void | ||
1288 | stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) | 1310 | stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) |
1289 | { | 1311 | { |
1290 | int i; | 1312 | int i; |
@@ -1311,15 +1333,14 @@ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) | |||
1311 | udc_reinit(dev); | 1333 | udc_reinit(dev); |
1312 | } | 1334 | } |
1313 | 1335 | ||
1314 | static int pxa25x_udc_stop(struct usb_gadget*g, | 1336 | static int pxa25x_udc_stop(struct usb_gadget*g) |
1315 | struct usb_gadget_driver *driver) | ||
1316 | { | 1337 | { |
1317 | struct pxa25x_udc *dev = to_pxa25x(g); | 1338 | struct pxa25x_udc *dev = to_pxa25x(g); |
1318 | 1339 | ||
1319 | local_irq_disable(); | 1340 | local_irq_disable(); |
1320 | dev->pullup = 0; | 1341 | dev->pullup = 0; |
1321 | pullup(dev); | 1342 | pullup(dev); |
1322 | stop_activity(dev, driver); | 1343 | stop_activity(dev, NULL); |
1323 | local_irq_enable(); | 1344 | local_irq_enable(); |
1324 | 1345 | ||
1325 | if (!IS_ERR_OR_NULL(dev->transceiver)) | 1346 | if (!IS_ERR_OR_NULL(dev->transceiver)) |
@@ -1723,7 +1744,7 @@ pxa25x_udc_irq(int irq, void *_dev) | |||
1723 | /* reset driver and endpoints, | 1744 | /* reset driver and endpoints, |
1724 | * in case that's not yet done | 1745 | * in case that's not yet done |
1725 | */ | 1746 | */ |
1726 | stop_activity (dev, dev->driver); | 1747 | reset_gadget(dev, dev->driver); |
1727 | 1748 | ||
1728 | } else { | 1749 | } else { |
1729 | DBG(DBG_VERBOSE, "USB reset end\n"); | 1750 | DBG(DBG_VERBOSE, "USB reset end\n"); |
diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index 4868369eeec6..9b03fab13707 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c | |||
@@ -22,10 +22,13 @@ | |||
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
25 | #include <linux/gpio/consumer.h> | ||
25 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
26 | #include <linux/prefetch.h> | 27 | #include <linux/prefetch.h> |
27 | #include <linux/byteorder/generic.h> | 28 | #include <linux/byteorder/generic.h> |
28 | #include <linux/platform_data/pxa2xx_udc.h> | 29 | #include <linux/platform_data/pxa2xx_udc.h> |
30 | #include <linux/of_device.h> | ||
31 | #include <linux/of_gpio.h> | ||
29 | 32 | ||
30 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
31 | #include <linux/usb/ch9.h> | 34 | #include <linux/usb/ch9.h> |
@@ -1507,18 +1510,13 @@ static struct usb_ep_ops pxa_ep_ops = { | |||
1507 | */ | 1510 | */ |
1508 | static void dplus_pullup(struct pxa_udc *udc, int on) | 1511 | static void dplus_pullup(struct pxa_udc *udc, int on) |
1509 | { | 1512 | { |
1510 | if (on) { | 1513 | if (udc->gpiod) { |
1511 | if (gpio_is_valid(udc->mach->gpio_pullup)) | 1514 | gpiod_set_value(udc->gpiod, on); |
1512 | gpio_set_value(udc->mach->gpio_pullup, | 1515 | } else if (udc->udc_command) { |
1513 | !udc->mach->gpio_pullup_inverted); | 1516 | if (on) |
1514 | if (udc->mach->udc_command) | 1517 | udc->udc_command(PXA2XX_UDC_CMD_CONNECT); |
1515 | udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | 1518 | else |
1516 | } else { | 1519 | udc->udc_command(PXA2XX_UDC_CMD_DISCONNECT); |
1517 | if (gpio_is_valid(udc->mach->gpio_pullup)) | ||
1518 | gpio_set_value(udc->mach->gpio_pullup, | ||
1519 | udc->mach->gpio_pullup_inverted); | ||
1520 | if (udc->mach->udc_command) | ||
1521 | udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | ||
1522 | } | 1520 | } |
1523 | udc->pullup_on = on; | 1521 | udc->pullup_on = on; |
1524 | } | 1522 | } |
@@ -1609,7 +1607,7 @@ static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active) | |||
1609 | { | 1607 | { |
1610 | struct pxa_udc *udc = to_gadget_udc(_gadget); | 1608 | struct pxa_udc *udc = to_gadget_udc(_gadget); |
1611 | 1609 | ||
1612 | if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) | 1610 | if (!udc->gpiod && !udc->udc_command) |
1613 | return -EOPNOTSUPP; | 1611 | return -EOPNOTSUPP; |
1614 | 1612 | ||
1615 | dplus_pullup(udc, is_active); | 1613 | dplus_pullup(udc, is_active); |
@@ -1671,8 +1669,7 @@ static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | |||
1671 | 1669 | ||
1672 | static int pxa27x_udc_start(struct usb_gadget *g, | 1670 | static int pxa27x_udc_start(struct usb_gadget *g, |
1673 | struct usb_gadget_driver *driver); | 1671 | struct usb_gadget_driver *driver); |
1674 | static int pxa27x_udc_stop(struct usb_gadget *g, | 1672 | static int pxa27x_udc_stop(struct usb_gadget *g); |
1675 | struct usb_gadget_driver *driver); | ||
1676 | 1673 | ||
1677 | static const struct usb_gadget_ops pxa_udc_ops = { | 1674 | static const struct usb_gadget_ops pxa_udc_ops = { |
1678 | .get_frame = pxa_udc_get_frame, | 1675 | .get_frame = pxa_udc_get_frame, |
@@ -1701,10 +1698,10 @@ static void udc_disable(struct pxa_udc *udc) | |||
1701 | udc_writel(udc, UDCICR1, 0); | 1698 | udc_writel(udc, UDCICR1, 0); |
1702 | 1699 | ||
1703 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); | 1700 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); |
1704 | clk_disable(udc->clk); | ||
1705 | 1701 | ||
1706 | ep0_idle(udc); | 1702 | ep0_idle(udc); |
1707 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1703 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1704 | clk_disable(udc->clk); | ||
1708 | 1705 | ||
1709 | udc->enabled = 0; | 1706 | udc->enabled = 0; |
1710 | } | 1707 | } |
@@ -1757,16 +1754,16 @@ static void udc_enable(struct pxa_udc *udc) | |||
1757 | if (udc->enabled) | 1754 | if (udc->enabled) |
1758 | return; | 1755 | return; |
1759 | 1756 | ||
1757 | clk_enable(udc->clk); | ||
1760 | udc_writel(udc, UDCICR0, 0); | 1758 | udc_writel(udc, UDCICR0, 0); |
1761 | udc_writel(udc, UDCICR1, 0); | 1759 | udc_writel(udc, UDCICR1, 0); |
1762 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); | 1760 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); |
1763 | 1761 | ||
1764 | clk_enable(udc->clk); | ||
1765 | |||
1766 | ep0_idle(udc); | 1762 | ep0_idle(udc); |
1767 | udc->gadget.speed = USB_SPEED_FULL; | 1763 | udc->gadget.speed = USB_SPEED_FULL; |
1768 | memset(&udc->stats, 0, sizeof(udc->stats)); | 1764 | memset(&udc->stats, 0, sizeof(udc->stats)); |
1769 | 1765 | ||
1766 | pxa_eps_setup(udc); | ||
1770 | udc_set_mask_UDCCR(udc, UDCCR_UDE); | 1767 | udc_set_mask_UDCCR(udc, UDCCR_UDE); |
1771 | ep_write_UDCCSR(&udc->pxa_ep[0], UDCCSR0_ACM); | 1768 | ep_write_UDCCSR(&udc->pxa_ep[0], UDCCSR0_ACM); |
1772 | udelay(2); | 1769 | udelay(2); |
@@ -1859,12 +1856,11 @@ static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver) | |||
1859 | * | 1856 | * |
1860 | * Returns 0 if no error, -ENODEV, -EINVAL otherwise | 1857 | * Returns 0 if no error, -ENODEV, -EINVAL otherwise |
1861 | */ | 1858 | */ |
1862 | static int pxa27x_udc_stop(struct usb_gadget *g, | 1859 | static int pxa27x_udc_stop(struct usb_gadget *g) |
1863 | struct usb_gadget_driver *driver) | ||
1864 | { | 1860 | { |
1865 | struct pxa_udc *udc = to_pxa(g); | 1861 | struct pxa_udc *udc = to_pxa(g); |
1866 | 1862 | ||
1867 | stop_activity(udc, driver); | 1863 | stop_activity(udc, NULL); |
1868 | udc_disable(udc); | 1864 | udc_disable(udc); |
1869 | dplus_pullup(udc, 0); | 1865 | dplus_pullup(udc, 0); |
1870 | 1866 | ||
@@ -2404,6 +2400,14 @@ static struct pxa_udc memory = { | |||
2404 | } | 2400 | } |
2405 | }; | 2401 | }; |
2406 | 2402 | ||
2403 | #if defined(CONFIG_OF) | ||
2404 | static struct of_device_id udc_pxa_dt_ids[] = { | ||
2405 | { .compatible = "marvell,pxa270-udc" }, | ||
2406 | {} | ||
2407 | }; | ||
2408 | MODULE_DEVICE_TABLE(of, udc_pxa_dt_ids); | ||
2409 | #endif | ||
2410 | |||
2407 | /** | 2411 | /** |
2408 | * pxa_udc_probe - probes the udc device | 2412 | * pxa_udc_probe - probes the udc device |
2409 | * @_dev: platform device | 2413 | * @_dev: platform device |
@@ -2416,81 +2420,77 @@ static int pxa_udc_probe(struct platform_device *pdev) | |||
2416 | struct resource *regs; | 2420 | struct resource *regs; |
2417 | struct pxa_udc *udc = &memory; | 2421 | struct pxa_udc *udc = &memory; |
2418 | int retval = 0, gpio; | 2422 | int retval = 0, gpio; |
2423 | struct pxa2xx_udc_mach_info *mach = dev_get_platdata(&pdev->dev); | ||
2424 | unsigned long gpio_flags; | ||
2425 | |||
2426 | if (mach) { | ||
2427 | gpio_flags = mach->gpio_pullup_inverted ? GPIOF_ACTIVE_LOW : 0; | ||
2428 | gpio = mach->gpio_pullup; | ||
2429 | if (gpio_is_valid(gpio)) { | ||
2430 | retval = devm_gpio_request_one(&pdev->dev, gpio, | ||
2431 | gpio_flags, | ||
2432 | "USB D+ pullup"); | ||
2433 | if (retval) | ||
2434 | return retval; | ||
2435 | udc->gpiod = gpio_to_desc(mach->gpio_pullup); | ||
2436 | } | ||
2437 | udc->udc_command = mach->udc_command; | ||
2438 | } else { | ||
2439 | udc->gpiod = devm_gpiod_get(&pdev->dev, NULL); | ||
2440 | } | ||
2419 | 2441 | ||
2420 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2442 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2421 | if (!regs) | 2443 | udc->regs = devm_ioremap_resource(&pdev->dev, regs); |
2422 | return -ENXIO; | 2444 | if (IS_ERR(udc->regs)) |
2445 | return PTR_ERR(udc->regs); | ||
2423 | udc->irq = platform_get_irq(pdev, 0); | 2446 | udc->irq = platform_get_irq(pdev, 0); |
2424 | if (udc->irq < 0) | 2447 | if (udc->irq < 0) |
2425 | return udc->irq; | 2448 | return udc->irq; |
2426 | 2449 | ||
2427 | udc->dev = &pdev->dev; | 2450 | udc->dev = &pdev->dev; |
2428 | udc->mach = dev_get_platdata(&pdev->dev); | ||
2429 | udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); | 2451 | udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); |
2430 | 2452 | ||
2431 | gpio = udc->mach->gpio_pullup; | 2453 | if (IS_ERR(udc->gpiod)) { |
2432 | if (gpio_is_valid(gpio)) { | 2454 | dev_err(&pdev->dev, "Couldn't find or request D+ gpio : %ld\n", |
2433 | retval = gpio_request(gpio, "USB D+ pullup"); | 2455 | PTR_ERR(udc->gpiod)); |
2434 | if (retval == 0) | 2456 | return PTR_ERR(udc->gpiod); |
2435 | gpio_direction_output(gpio, | ||
2436 | udc->mach->gpio_pullup_inverted); | ||
2437 | } | ||
2438 | if (retval) { | ||
2439 | dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n", | ||
2440 | gpio, retval); | ||
2441 | return retval; | ||
2442 | } | 2457 | } |
2458 | if (udc->gpiod) | ||
2459 | gpiod_direction_output(udc->gpiod, 0); | ||
2460 | |||
2461 | udc->clk = devm_clk_get(&pdev->dev, NULL); | ||
2462 | if (IS_ERR(udc->clk)) | ||
2463 | return PTR_ERR(udc->clk); | ||
2443 | 2464 | ||
2444 | udc->clk = clk_get(&pdev->dev, NULL); | ||
2445 | if (IS_ERR(udc->clk)) { | ||
2446 | retval = PTR_ERR(udc->clk); | ||
2447 | goto err_clk; | ||
2448 | } | ||
2449 | retval = clk_prepare(udc->clk); | 2465 | retval = clk_prepare(udc->clk); |
2450 | if (retval) | 2466 | if (retval) |
2451 | goto err_clk_prepare; | 2467 | return retval; |
2452 | |||
2453 | retval = -ENOMEM; | ||
2454 | udc->regs = ioremap(regs->start, resource_size(regs)); | ||
2455 | if (!udc->regs) { | ||
2456 | dev_err(&pdev->dev, "Unable to map UDC I/O memory\n"); | ||
2457 | goto err_map; | ||
2458 | } | ||
2459 | 2468 | ||
2460 | udc->vbus_sensed = 0; | 2469 | udc->vbus_sensed = 0; |
2461 | 2470 | ||
2462 | the_controller = udc; | 2471 | the_controller = udc; |
2463 | platform_set_drvdata(pdev, udc); | 2472 | platform_set_drvdata(pdev, udc); |
2464 | udc_init_data(udc); | 2473 | udc_init_data(udc); |
2465 | pxa_eps_setup(udc); | ||
2466 | 2474 | ||
2467 | /* irq setup after old hardware state is cleaned up */ | 2475 | /* irq setup after old hardware state is cleaned up */ |
2468 | retval = request_irq(udc->irq, pxa_udc_irq, | 2476 | retval = devm_request_irq(&pdev->dev, udc->irq, pxa_udc_irq, |
2469 | IRQF_SHARED, driver_name, udc); | 2477 | IRQF_SHARED, driver_name, udc); |
2470 | if (retval != 0) { | 2478 | if (retval != 0) { |
2471 | dev_err(udc->dev, "%s: can't get irq %i, err %d\n", | 2479 | dev_err(udc->dev, "%s: can't get irq %i, err %d\n", |
2472 | driver_name, udc->irq, retval); | 2480 | driver_name, udc->irq, retval); |
2473 | goto err_irq; | 2481 | goto err; |
2474 | } | 2482 | } |
2475 | 2483 | ||
2476 | retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); | 2484 | retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); |
2477 | if (retval) | 2485 | if (retval) |
2478 | goto err_add_udc; | 2486 | goto err; |
2479 | 2487 | ||
2480 | pxa_init_debugfs(udc); | 2488 | pxa_init_debugfs(udc); |
2481 | 2489 | if (should_enable_udc(udc)) | |
2490 | udc_enable(udc); | ||
2482 | return 0; | 2491 | return 0; |
2483 | 2492 | err: | |
2484 | err_add_udc: | ||
2485 | free_irq(udc->irq, udc); | ||
2486 | err_irq: | ||
2487 | iounmap(udc->regs); | ||
2488 | err_map: | ||
2489 | clk_unprepare(udc->clk); | 2493 | clk_unprepare(udc->clk); |
2490 | err_clk_prepare: | ||
2491 | clk_put(udc->clk); | ||
2492 | udc->clk = NULL; | ||
2493 | err_clk: | ||
2494 | return retval; | 2494 | return retval; |
2495 | } | 2495 | } |
2496 | 2496 | ||
@@ -2501,22 +2501,15 @@ err_clk: | |||
2501 | static int pxa_udc_remove(struct platform_device *_dev) | 2501 | static int pxa_udc_remove(struct platform_device *_dev) |
2502 | { | 2502 | { |
2503 | struct pxa_udc *udc = platform_get_drvdata(_dev); | 2503 | struct pxa_udc *udc = platform_get_drvdata(_dev); |
2504 | int gpio = udc->mach->gpio_pullup; | ||
2505 | 2504 | ||
2506 | usb_del_gadget_udc(&udc->gadget); | 2505 | usb_del_gadget_udc(&udc->gadget); |
2507 | usb_gadget_unregister_driver(udc->driver); | ||
2508 | free_irq(udc->irq, udc); | ||
2509 | pxa_cleanup_debugfs(udc); | 2506 | pxa_cleanup_debugfs(udc); |
2510 | if (gpio_is_valid(gpio)) | ||
2511 | gpio_free(gpio); | ||
2512 | 2507 | ||
2513 | usb_put_phy(udc->transceiver); | 2508 | usb_put_phy(udc->transceiver); |
2514 | 2509 | ||
2515 | udc->transceiver = NULL; | 2510 | udc->transceiver = NULL; |
2516 | the_controller = NULL; | 2511 | the_controller = NULL; |
2517 | clk_unprepare(udc->clk); | 2512 | clk_unprepare(udc->clk); |
2518 | clk_put(udc->clk); | ||
2519 | iounmap(udc->regs); | ||
2520 | 2513 | ||
2521 | return 0; | 2514 | return 0; |
2522 | } | 2515 | } |
@@ -2546,19 +2539,11 @@ extern void pxa27x_clear_otgph(void); | |||
2546 | */ | 2539 | */ |
2547 | static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) | 2540 | static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) |
2548 | { | 2541 | { |
2549 | int i; | ||
2550 | struct pxa_udc *udc = platform_get_drvdata(_dev); | 2542 | struct pxa_udc *udc = platform_get_drvdata(_dev); |
2551 | struct pxa_ep *ep; | 2543 | struct pxa_ep *ep; |
2552 | 2544 | ||
2553 | ep = &udc->pxa_ep[0]; | 2545 | ep = &udc->pxa_ep[0]; |
2554 | udc->udccsr0 = udc_ep_readl(ep, UDCCSR); | 2546 | udc->udccsr0 = udc_ep_readl(ep, UDCCSR); |
2555 | for (i = 1; i < NR_PXA_ENDPOINTS; i++) { | ||
2556 | ep = &udc->pxa_ep[i]; | ||
2557 | ep->udccsr_value = udc_ep_readl(ep, UDCCSR); | ||
2558 | ep->udccr_value = udc_ep_readl(ep, UDCCR); | ||
2559 | ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n", | ||
2560 | ep->udccsr_value, ep->udccr_value); | ||
2561 | } | ||
2562 | 2547 | ||
2563 | udc_disable(udc); | 2548 | udc_disable(udc); |
2564 | udc->pullup_resume = udc->pullup_on; | 2549 | udc->pullup_resume = udc->pullup_on; |
@@ -2576,19 +2561,11 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) | |||
2576 | */ | 2561 | */ |
2577 | static int pxa_udc_resume(struct platform_device *_dev) | 2562 | static int pxa_udc_resume(struct platform_device *_dev) |
2578 | { | 2563 | { |
2579 | int i; | ||
2580 | struct pxa_udc *udc = platform_get_drvdata(_dev); | 2564 | struct pxa_udc *udc = platform_get_drvdata(_dev); |
2581 | struct pxa_ep *ep; | 2565 | struct pxa_ep *ep; |
2582 | 2566 | ||
2583 | ep = &udc->pxa_ep[0]; | 2567 | ep = &udc->pxa_ep[0]; |
2584 | udc_ep_writel(ep, UDCCSR, udc->udccsr0 & (UDCCSR0_FST | UDCCSR0_DME)); | 2568 | udc_ep_writel(ep, UDCCSR, udc->udccsr0 & (UDCCSR0_FST | UDCCSR0_DME)); |
2585 | for (i = 1; i < NR_PXA_ENDPOINTS; i++) { | ||
2586 | ep = &udc->pxa_ep[i]; | ||
2587 | udc_ep_writel(ep, UDCCSR, ep->udccsr_value); | ||
2588 | udc_ep_writel(ep, UDCCR, ep->udccr_value); | ||
2589 | ep_dbg(ep, "udccsr:0x%03x, udccr:0x%x\n", | ||
2590 | ep->udccsr_value, ep->udccr_value); | ||
2591 | } | ||
2592 | 2569 | ||
2593 | dplus_pullup(udc, udc->pullup_resume); | 2570 | dplus_pullup(udc, udc->pullup_resume); |
2594 | if (should_enable_udc(udc)) | 2571 | if (should_enable_udc(udc)) |
@@ -2615,6 +2592,7 @@ static struct platform_driver udc_driver = { | |||
2615 | .driver = { | 2592 | .driver = { |
2616 | .name = "pxa27x-udc", | 2593 | .name = "pxa27x-udc", |
2617 | .owner = THIS_MODULE, | 2594 | .owner = THIS_MODULE, |
2595 | .of_match_table = of_match_ptr(udc_pxa_dt_ids), | ||
2618 | }, | 2596 | }, |
2619 | .probe = pxa_udc_probe, | 2597 | .probe = pxa_udc_probe, |
2620 | .remove = pxa_udc_remove, | 2598 | .remove = pxa_udc_remove, |
diff --git a/drivers/usb/gadget/udc/pxa27x_udc.h b/drivers/usb/gadget/udc/pxa27x_udc.h index 28f2b53530f5..11e14232794b 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.h +++ b/drivers/usb/gadget/udc/pxa27x_udc.h | |||
@@ -420,7 +420,8 @@ struct udc_stats { | |||
420 | * @usb_gadget: udc gadget structure | 420 | * @usb_gadget: udc gadget structure |
421 | * @driver: bound gadget (zero, g_ether, g_mass_storage, ...) | 421 | * @driver: bound gadget (zero, g_ether, g_mass_storage, ...) |
422 | * @dev: device | 422 | * @dev: device |
423 | * @mach: machine info, used to activate specific GPIO | 423 | * @udc_command: machine specific function to activate D+ pullup |
424 | * @gpiod: gpio descriptor of gpio for D+ pullup (or NULL if none) | ||
424 | * @transceiver: external transceiver to handle vbus sense and D+ pullup | 425 | * @transceiver: external transceiver to handle vbus sense and D+ pullup |
425 | * @ep0state: control endpoint state machine state | 426 | * @ep0state: control endpoint state machine state |
426 | * @stats: statistics on udc usage | 427 | * @stats: statistics on udc usage |
@@ -446,7 +447,8 @@ struct pxa_udc { | |||
446 | struct usb_gadget gadget; | 447 | struct usb_gadget gadget; |
447 | struct usb_gadget_driver *driver; | 448 | struct usb_gadget_driver *driver; |
448 | struct device *dev; | 449 | struct device *dev; |
449 | struct pxa2xx_udc_mach_info *mach; | 450 | void (*udc_command)(int); |
451 | struct gpio_desc *gpiod; | ||
450 | struct usb_phy *transceiver; | 452 | struct usb_phy *transceiver; |
451 | 453 | ||
452 | enum ep0_state ep0state; | 454 | enum ep0_state ep0state; |
diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index f8186613b53e..06870da0b988 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c | |||
@@ -1345,7 +1345,7 @@ static void irq_device_state(struct r8a66597 *r8a66597) | |||
1345 | if (dvsq == DS_DFLT) { | 1345 | if (dvsq == DS_DFLT) { |
1346 | /* bus reset */ | 1346 | /* bus reset */ |
1347 | spin_unlock(&r8a66597->lock); | 1347 | spin_unlock(&r8a66597->lock); |
1348 | r8a66597->driver->disconnect(&r8a66597->gadget); | 1348 | usb_gadget_udc_reset(&r8a66597->gadget, r8a66597->driver); |
1349 | spin_lock(&r8a66597->lock); | 1349 | spin_lock(&r8a66597->lock); |
1350 | r8a66597_update_usb_speed(r8a66597); | 1350 | r8a66597_update_usb_speed(r8a66597); |
1351 | } | 1351 | } |
@@ -1763,8 +1763,7 @@ static int r8a66597_start(struct usb_gadget *gadget, | |||
1763 | return 0; | 1763 | return 0; |
1764 | } | 1764 | } |
1765 | 1765 | ||
1766 | static int r8a66597_stop(struct usb_gadget *gadget, | 1766 | static int r8a66597_stop(struct usb_gadget *gadget) |
1767 | struct usb_gadget_driver *driver) | ||
1768 | { | 1767 | { |
1769 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); | 1768 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); |
1770 | unsigned long flags; | 1769 | unsigned long flags; |
@@ -1846,10 +1845,7 @@ static int r8a66597_sudmac_ioremap(struct r8a66597 *r8a66597, | |||
1846 | 1845 | ||
1847 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sudmac"); | 1846 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sudmac"); |
1848 | r8a66597->sudmac_reg = devm_ioremap_resource(&pdev->dev, res); | 1847 | r8a66597->sudmac_reg = devm_ioremap_resource(&pdev->dev, res); |
1849 | if (IS_ERR(r8a66597->sudmac_reg)) | 1848 | return PTR_ERR_OR_ZERO(r8a66597->sudmac_reg); |
1850 | return PTR_ERR(r8a66597->sudmac_reg); | ||
1851 | |||
1852 | return 0; | ||
1853 | } | 1849 | } |
1854 | 1850 | ||
1855 | static int r8a66597_probe(struct platform_device *pdev) | 1851 | static int r8a66597_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/gadget/udc/s3c-hsudc.c b/drivers/usb/gadget/udc/s3c-hsudc.c index dfbf55797360..97d3a9144381 100644 --- a/drivers/usb/gadget/udc/s3c-hsudc.c +++ b/drivers/usb/gadget/udc/s3c-hsudc.c | |||
@@ -1172,8 +1172,6 @@ static int s3c_hsudc_start(struct usb_gadget *gadget, | |||
1172 | } | 1172 | } |
1173 | 1173 | ||
1174 | enable_irq(hsudc->irq); | 1174 | enable_irq(hsudc->irq); |
1175 | dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name); | ||
1176 | |||
1177 | s3c_hsudc_reconfig(hsudc); | 1175 | s3c_hsudc_reconfig(hsudc); |
1178 | 1176 | ||
1179 | pm_runtime_get_sync(hsudc->dev); | 1177 | pm_runtime_get_sync(hsudc->dev); |
@@ -1190,8 +1188,7 @@ err_supplies: | |||
1190 | return ret; | 1188 | return ret; |
1191 | } | 1189 | } |
1192 | 1190 | ||
1193 | static int s3c_hsudc_stop(struct usb_gadget *gadget, | 1191 | static int s3c_hsudc_stop(struct usb_gadget *gadget) |
1194 | struct usb_gadget_driver *driver) | ||
1195 | { | 1192 | { |
1196 | struct s3c_hsudc *hsudc = to_hsudc(gadget); | 1193 | struct s3c_hsudc *hsudc = to_hsudc(gadget); |
1197 | unsigned long flags; | 1194 | unsigned long flags; |
@@ -1199,11 +1196,7 @@ static int s3c_hsudc_stop(struct usb_gadget *gadget, | |||
1199 | if (!hsudc) | 1196 | if (!hsudc) |
1200 | return -ENODEV; | 1197 | return -ENODEV; |
1201 | 1198 | ||
1202 | if (!driver || driver != hsudc->driver) | ||
1203 | return -EINVAL; | ||
1204 | |||
1205 | spin_lock_irqsave(&hsudc->lock, flags); | 1199 | spin_lock_irqsave(&hsudc->lock, flags); |
1206 | hsudc->driver = NULL; | ||
1207 | hsudc->gadget.speed = USB_SPEED_UNKNOWN; | 1200 | hsudc->gadget.speed = USB_SPEED_UNKNOWN; |
1208 | s3c_hsudc_uninit_phy(); | 1201 | s3c_hsudc_uninit_phy(); |
1209 | 1202 | ||
@@ -1220,9 +1213,8 @@ static int s3c_hsudc_stop(struct usb_gadget *gadget, | |||
1220 | disable_irq(hsudc->irq); | 1213 | disable_irq(hsudc->irq); |
1221 | 1214 | ||
1222 | regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); | 1215 | regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); |
1216 | hsudc->driver = NULL; | ||
1223 | 1217 | ||
1224 | dev_info(hsudc->dev, "unregistered gadget driver '%s'\n", | ||
1225 | driver->driver.name); | ||
1226 | return 0; | 1218 | return 0; |
1227 | } | 1219 | } |
1228 | 1220 | ||
@@ -1267,10 +1259,8 @@ static int s3c_hsudc_probe(struct platform_device *pdev) | |||
1267 | hsudc = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsudc) + | 1259 | hsudc = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsudc) + |
1268 | sizeof(struct s3c_hsudc_ep) * pd->epnum, | 1260 | sizeof(struct s3c_hsudc_ep) * pd->epnum, |
1269 | GFP_KERNEL); | 1261 | GFP_KERNEL); |
1270 | if (!hsudc) { | 1262 | if (!hsudc) |
1271 | dev_err(dev, "cannot allocate memory\n"); | ||
1272 | return -ENOMEM; | 1263 | return -ENOMEM; |
1273 | } | ||
1274 | 1264 | ||
1275 | platform_set_drvdata(pdev, dev); | 1265 | platform_set_drvdata(pdev, dev); |
1276 | hsudc->dev = dev; | 1266 | hsudc->dev = dev; |
diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index ff423d15beff..2a8e36d31488 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c | |||
@@ -1541,8 +1541,7 @@ static int s3c2410_vbus_draw(struct usb_gadget *_gadget, unsigned ma) | |||
1541 | 1541 | ||
1542 | static int s3c2410_udc_start(struct usb_gadget *g, | 1542 | static int s3c2410_udc_start(struct usb_gadget *g, |
1543 | struct usb_gadget_driver *driver); | 1543 | struct usb_gadget_driver *driver); |
1544 | static int s3c2410_udc_stop(struct usb_gadget *g, | 1544 | static int s3c2410_udc_stop(struct usb_gadget *g); |
1545 | struct usb_gadget_driver *driver); | ||
1546 | 1545 | ||
1547 | static const struct usb_gadget_ops s3c2410_ops = { | 1546 | static const struct usb_gadget_ops s3c2410_ops = { |
1548 | .get_frame = s3c2410_udc_get_frame, | 1547 | .get_frame = s3c2410_udc_get_frame, |
@@ -1683,8 +1682,7 @@ static int s3c2410_udc_start(struct usb_gadget *g, | |||
1683 | return 0; | 1682 | return 0; |
1684 | } | 1683 | } |
1685 | 1684 | ||
1686 | static int s3c2410_udc_stop(struct usb_gadget *g, | 1685 | static int s3c2410_udc_stop(struct usb_gadget *g) |
1687 | struct usb_gadget_driver *driver) | ||
1688 | { | 1686 | { |
1689 | struct s3c2410_udc *udc = to_s3c2410(g); | 1687 | struct s3c2410_udc *udc = to_s3c2410(g); |
1690 | 1688 | ||
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index f2054659f25b..e31d574d8860 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c | |||
@@ -174,8 +174,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_udc_reset); | |||
174 | 174 | ||
175 | /** | 175 | /** |
176 | * usb_gadget_udc_start - tells usb device controller to start up | 176 | * usb_gadget_udc_start - tells usb device controller to start up |
177 | * @gadget: The gadget we want to get started | 177 | * @udc: The UDC to be started |
178 | * @driver: The driver we want to bind to @gadget | ||
179 | * | 178 | * |
180 | * This call is issued by the UDC Class driver when it's about | 179 | * This call is issued by the UDC Class driver when it's about |
181 | * to register a gadget driver to the device controller, before | 180 | * to register a gadget driver to the device controller, before |
@@ -186,10 +185,9 @@ EXPORT_SYMBOL_GPL(usb_gadget_udc_reset); | |||
186 | * | 185 | * |
187 | * Returns zero on success, else negative errno. | 186 | * Returns zero on success, else negative errno. |
188 | */ | 187 | */ |
189 | static inline int usb_gadget_udc_start(struct usb_gadget *gadget, | 188 | static inline int usb_gadget_udc_start(struct usb_udc *udc) |
190 | struct usb_gadget_driver *driver) | ||
191 | { | 189 | { |
192 | return gadget->ops->udc_start(gadget, driver); | 190 | return udc->gadget->ops->udc_start(udc->gadget, udc->driver); |
193 | } | 191 | } |
194 | 192 | ||
195 | /** | 193 | /** |
@@ -204,10 +202,9 @@ static inline int usb_gadget_udc_start(struct usb_gadget *gadget, | |||
204 | * far as powering off UDC completely and disable its data | 202 | * far as powering off UDC completely and disable its data |
205 | * line pullups. | 203 | * line pullups. |
206 | */ | 204 | */ |
207 | static inline void usb_gadget_udc_stop(struct usb_gadget *gadget, | 205 | static inline void usb_gadget_udc_stop(struct usb_udc *udc) |
208 | struct usb_gadget_driver *driver) | ||
209 | { | 206 | { |
210 | gadget->ops->udc_stop(gadget, driver); | 207 | udc->gadget->ops->udc_stop(udc->gadget); |
211 | } | 208 | } |
212 | 209 | ||
213 | /** | 210 | /** |
@@ -328,14 +325,14 @@ EXPORT_SYMBOL_GPL(usb_add_gadget_udc); | |||
328 | static void usb_gadget_remove_driver(struct usb_udc *udc) | 325 | static void usb_gadget_remove_driver(struct usb_udc *udc) |
329 | { | 326 | { |
330 | dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n", | 327 | dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n", |
331 | udc->gadget->name); | 328 | udc->driver->function); |
332 | 329 | ||
333 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); | 330 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); |
334 | 331 | ||
335 | usb_gadget_disconnect(udc->gadget); | 332 | usb_gadget_disconnect(udc->gadget); |
336 | udc->driver->disconnect(udc->gadget); | 333 | udc->driver->disconnect(udc->gadget); |
337 | udc->driver->unbind(udc->gadget); | 334 | udc->driver->unbind(udc->gadget); |
338 | usb_gadget_udc_stop(udc->gadget, NULL); | 335 | usb_gadget_udc_stop(udc); |
339 | 336 | ||
340 | udc->driver = NULL; | 337 | udc->driver = NULL; |
341 | udc->dev.driver = NULL; | 338 | udc->dev.driver = NULL; |
@@ -395,7 +392,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri | |||
395 | ret = driver->bind(udc->gadget, driver); | 392 | ret = driver->bind(udc->gadget, driver); |
396 | if (ret) | 393 | if (ret) |
397 | goto err1; | 394 | goto err1; |
398 | ret = usb_gadget_udc_start(udc->gadget, driver); | 395 | ret = usb_gadget_udc_start(udc); |
399 | if (ret) { | 396 | if (ret) { |
400 | driver->unbind(udc->gadget); | 397 | driver->unbind(udc->gadget); |
401 | goto err1; | 398 | goto err1; |
@@ -414,7 +411,7 @@ err1: | |||
414 | return ret; | 411 | return ret; |
415 | } | 412 | } |
416 | 413 | ||
417 | int udc_attach_driver(const char *name, struct usb_gadget_driver *driver) | 414 | int usb_udc_attach_driver(const char *name, struct usb_gadget_driver *driver) |
418 | { | 415 | { |
419 | struct usb_udc *udc = NULL; | 416 | struct usb_udc *udc = NULL; |
420 | int ret = -ENODEV; | 417 | int ret = -ENODEV; |
@@ -438,7 +435,7 @@ out: | |||
438 | mutex_unlock(&udc_lock); | 435 | mutex_unlock(&udc_lock); |
439 | return ret; | 436 | return ret; |
440 | } | 437 | } |
441 | EXPORT_SYMBOL_GPL(udc_attach_driver); | 438 | EXPORT_SYMBOL_GPL(usb_udc_attach_driver); |
442 | 439 | ||
443 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver) | 440 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver) |
444 | { | 441 | { |
@@ -513,11 +510,12 @@ static ssize_t usb_udc_softconn_store(struct device *dev, | |||
513 | } | 510 | } |
514 | 511 | ||
515 | if (sysfs_streq(buf, "connect")) { | 512 | if (sysfs_streq(buf, "connect")) { |
516 | usb_gadget_udc_start(udc->gadget, udc->driver); | 513 | usb_gadget_udc_start(udc); |
517 | usb_gadget_connect(udc->gadget); | 514 | usb_gadget_connect(udc->gadget); |
518 | } else if (sysfs_streq(buf, "disconnect")) { | 515 | } else if (sysfs_streq(buf, "disconnect")) { |
519 | usb_gadget_disconnect(udc->gadget); | 516 | usb_gadget_disconnect(udc->gadget); |
520 | usb_gadget_udc_stop(udc->gadget, udc->driver); | 517 | udc->driver->disconnect(udc->gadget); |
518 | usb_gadget_udc_stop(udc); | ||
521 | } else { | 519 | } else { |
522 | dev_err(dev, "unsupported command '%s'\n", buf); | 520 | dev_err(dev, "unsupported command '%s'\n", buf); |
523 | return -EINVAL; | 521 | return -EINVAL; |
diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c index ed27e1687a4e..1eac56fc384d 100644 --- a/drivers/usb/gadget/udc/udc-xilinx.c +++ b/drivers/usb/gadget/udc/udc-xilinx.c | |||
@@ -1403,8 +1403,7 @@ err: | |||
1403 | * | 1403 | * |
1404 | * Return: zero always | 1404 | * Return: zero always |
1405 | */ | 1405 | */ |
1406 | static int xudc_stop(struct usb_gadget *gadget, | 1406 | static int xudc_stop(struct usb_gadget *gadget) |
1407 | struct usb_gadget_driver *driver) | ||
1408 | { | 1407 | { |
1409 | struct xusb_udc *udc = to_udc(gadget); | 1408 | struct xusb_udc *udc = to_udc(gadget); |
1410 | unsigned long flags; | 1409 | unsigned long flags; |