diff options
Diffstat (limited to 'drivers/usb/gadget')
37 files changed, 441 insertions, 472 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 12a401a144b7..7ecb68a67411 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | menuconfig USB_GADGET | 16 | menuconfig USB_GADGET |
17 | tristate "USB Gadget Support" | 17 | tristate "USB Gadget Support" |
18 | select NLS | ||
18 | help | 19 | help |
19 | USB is a master/slave protocol, organized with one master | 20 | USB is a master/slave protocol, organized with one master |
20 | host (such as a PC) controlling up to 127 peripheral devices. | 21 | host (such as a PC) controlling up to 127 peripheral devices. |
@@ -124,7 +125,6 @@ config USB_GADGET_STORAGE_NUM_BUFFERS | |||
124 | # | 125 | # |
125 | choice | 126 | choice |
126 | prompt "USB Peripheral Controller" | 127 | prompt "USB Peripheral Controller" |
127 | depends on USB_GADGET | ||
128 | help | 128 | help |
129 | A USB device uses a controller to talk to its host. | 129 | A USB device uses a controller to talk to its host. |
130 | Systems should have only one such upstream link. | 130 | Systems should have only one such upstream link. |
@@ -234,7 +234,6 @@ config USB_R8A66597 | |||
234 | 234 | ||
235 | config USB_RENESAS_USBHS_UDC | 235 | config USB_RENESAS_USBHS_UDC |
236 | tristate 'Renesas USBHS controller' | 236 | tristate 'Renesas USBHS controller' |
237 | depends on SUPERH || ARCH_SHMOBILE | ||
238 | depends on USB_RENESAS_USBHS | 237 | depends on USB_RENESAS_USBHS |
239 | select USB_GADGET_DUALSPEED | 238 | select USB_GADGET_DUALSPEED |
240 | help | 239 | help |
@@ -309,25 +308,13 @@ config USB_S3C_HSUDC | |||
309 | 308 | ||
310 | This driver has been tested on S3C2416 and S3C2450 processors. | 309 | This driver has been tested on S3C2416 and S3C2450 processors. |
311 | 310 | ||
312 | config USB_PXA_U2O | 311 | config USB_MV_UDC |
313 | tristate "PXA9xx Processor USB2.0 controller" | 312 | tristate "Marvell USB2.0 Device Controller" |
314 | depends on ARCH_MMP | ||
315 | select USB_GADGET_DUALSPEED | 313 | select USB_GADGET_DUALSPEED |
316 | help | 314 | help |
317 | PXA9xx Processor series include a high speed USB2.0 device | 315 | Marvell Socs (including PXA and MMP series) include a high speed |
318 | controller, which support high speed and full speed USB peripheral. | 316 | USB2.0 OTG controller, which can be configured as high speed or |
319 | 317 | full speed USB peripheral. | |
320 | config USB_GADGET_DWC3 | ||
321 | tristate "DesignWare USB3.0 (DRD) Controller" | ||
322 | depends on USB_DWC3 | ||
323 | select USB_GADGET_DUALSPEED | ||
324 | select USB_GADGET_SUPERSPEED | ||
325 | help | ||
326 | DesignWare USB3.0 controller is a SuperSpeed USB3.0 Controller | ||
327 | which can be configured for peripheral-only, host-only, hub-only | ||
328 | and Dual-Role operation. This Controller was first integrated into | ||
329 | the OMAP5 series of processors. More information about the OMAP5 | ||
330 | version of this controller, refer to http://www.ti.com/omap5. | ||
331 | 318 | ||
332 | # | 319 | # |
333 | # Controllers available in both integrated and discrete versions | 320 | # Controllers available in both integrated and discrete versions |
@@ -543,12 +530,10 @@ endchoice | |||
543 | # Selected by UDC drivers that support high-speed operation. | 530 | # Selected by UDC drivers that support high-speed operation. |
544 | config USB_GADGET_DUALSPEED | 531 | config USB_GADGET_DUALSPEED |
545 | bool | 532 | bool |
546 | depends on USB_GADGET | ||
547 | 533 | ||
548 | # Selected by UDC drivers that support super-speed opperation | 534 | # Selected by UDC drivers that support super-speed opperation |
549 | config USB_GADGET_SUPERSPEED | 535 | config USB_GADGET_SUPERSPEED |
550 | bool | 536 | bool |
551 | depends on USB_GADGET | ||
552 | depends on USB_GADGET_DUALSPEED | 537 | depends on USB_GADGET_DUALSPEED |
553 | 538 | ||
554 | # | 539 | # |
@@ -556,7 +541,6 @@ config USB_GADGET_SUPERSPEED | |||
556 | # | 541 | # |
557 | choice | 542 | choice |
558 | tristate "USB Gadget Drivers" | 543 | tristate "USB Gadget Drivers" |
559 | depends on USB_GADGET | ||
560 | default USB_ETH | 544 | default USB_ETH |
561 | help | 545 | help |
562 | A Linux "Gadget Driver" talks to the USB Peripheral Controller | 546 | A Linux "Gadget Driver" talks to the USB Peripheral Controller |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index b54ac6190890..b7f6eefc3927 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -27,7 +27,7 @@ obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o | |||
27 | obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o | 27 | obj-$(CONFIG_USB_S3C_HSUDC) += s3c-hsudc.o |
28 | obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o | 28 | obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o |
29 | obj-$(CONFIG_USB_EG20T) += pch_udc.o | 29 | obj-$(CONFIG_USB_EG20T) += pch_udc.o |
30 | obj-$(CONFIG_USB_PXA_U2O) += mv_udc.o | 30 | obj-$(CONFIG_USB_MV_UDC) += mv_udc.o |
31 | mv_udc-y := mv_udc_core.o | 31 | mv_udc-y := mv_udc_core.o |
32 | obj-$(CONFIG_USB_CI13XXX_MSM) += ci13xxx_msm.o | 32 | obj-$(CONFIG_USB_CI13XXX_MSM) += ci13xxx_msm.o |
33 | obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o | 33 | obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o |
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 45f422ac103f..e9a2c5c44454 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -1959,7 +1959,7 @@ static int amd5536_start(struct usb_gadget_driver *driver, | |||
1959 | u32 tmp; | 1959 | u32 tmp; |
1960 | 1960 | ||
1961 | if (!driver || !bind || !driver->setup | 1961 | if (!driver || !bind || !driver->setup |
1962 | || driver->speed < USB_SPEED_HIGH) | 1962 | || driver->max_speed < USB_SPEED_HIGH) |
1963 | return -EINVAL; | 1963 | return -EINVAL; |
1964 | if (!dev) | 1964 | if (!dev) |
1965 | return -ENODEV; | 1965 | return -ENODEV; |
@@ -3349,7 +3349,7 @@ static int udc_probe(struct udc *dev) | |||
3349 | dev_set_name(&dev->gadget.dev, "gadget"); | 3349 | dev_set_name(&dev->gadget.dev, "gadget"); |
3350 | dev->gadget.dev.release = gadget_release; | 3350 | dev->gadget.dev.release = gadget_release; |
3351 | dev->gadget.name = name; | 3351 | dev->gadget.name = name; |
3352 | dev->gadget.is_dualspeed = 1; | 3352 | dev->gadget.max_speed = USB_SPEED_HIGH; |
3353 | 3353 | ||
3354 | /* init registers, interrupts, ... */ | 3354 | /* init registers, interrupts, ... */ |
3355 | startup_registers(dev); | 3355 | startup_registers(dev); |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 8efe0fa9228d..ac41f71bf9ca 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -1633,7 +1633,7 @@ static int at91_start(struct usb_gadget_driver *driver, | |||
1633 | unsigned long flags; | 1633 | unsigned long flags; |
1634 | 1634 | ||
1635 | if (!driver | 1635 | if (!driver |
1636 | || driver->speed < USB_SPEED_FULL | 1636 | || driver->max_speed < USB_SPEED_FULL |
1637 | || !bind | 1637 | || !bind |
1638 | || !driver->setup) { | 1638 | || !driver->setup) { |
1639 | DBG("bad parameter.\n"); | 1639 | DBG("bad parameter.\n"); |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 271a9d873608..e2fb6d583bd9 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -1038,7 +1038,7 @@ static struct usba_udc the_udc = { | |||
1038 | .gadget = { | 1038 | .gadget = { |
1039 | .ops = &usba_udc_ops, | 1039 | .ops = &usba_udc_ops, |
1040 | .ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list), | 1040 | .ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list), |
1041 | .is_dualspeed = 1, | 1041 | .max_speed = USB_SPEED_HIGH, |
1042 | .name = "atmel_usba_udc", | 1042 | .name = "atmel_usba_udc", |
1043 | .dev = { | 1043 | .dev = { |
1044 | .init_name = "gadget", | 1044 | .init_name = "gadget", |
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 9a0c3979ff43..27e313718422 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -182,6 +182,16 @@ static inline int hw_ep_bit(int num, int dir) | |||
182 | return num + (dir ? 16 : 0); | 182 | return num + (dir ? 16 : 0); |
183 | } | 183 | } |
184 | 184 | ||
185 | static int ep_to_bit(int n) | ||
186 | { | ||
187 | int fill = 16 - hw_ep_max / 2; | ||
188 | |||
189 | if (n >= hw_ep_max / 2) | ||
190 | n += fill; | ||
191 | |||
192 | return n; | ||
193 | } | ||
194 | |||
185 | /** | 195 | /** |
186 | * hw_aread: reads from register bitfield | 196 | * hw_aread: reads from register bitfield |
187 | * @addr: address relative to bus map | 197 | * @addr: address relative to bus map |
@@ -440,12 +450,13 @@ static int hw_ep_get_halt(int num, int dir) | |||
440 | /** | 450 | /** |
441 | * hw_test_and_clear_setup_status: test & clear setup status (execute without | 451 | * hw_test_and_clear_setup_status: test & clear setup status (execute without |
442 | * interruption) | 452 | * interruption) |
443 | * @n: bit number (endpoint) | 453 | * @n: endpoint number |
444 | * | 454 | * |
445 | * This function returns setup status | 455 | * This function returns setup status |
446 | */ | 456 | */ |
447 | static int hw_test_and_clear_setup_status(int n) | 457 | static int hw_test_and_clear_setup_status(int n) |
448 | { | 458 | { |
459 | n = ep_to_bit(n); | ||
449 | return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n)); | 460 | return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n)); |
450 | } | 461 | } |
451 | 462 | ||
@@ -641,12 +652,13 @@ static int hw_register_write(u16 addr, u32 data) | |||
641 | /** | 652 | /** |
642 | * hw_test_and_clear_complete: test & clear complete status (execute without | 653 | * hw_test_and_clear_complete: test & clear complete status (execute without |
643 | * interruption) | 654 | * interruption) |
644 | * @n: bit number (endpoint) | 655 | * @n: endpoint number |
645 | * | 656 | * |
646 | * This function returns complete status | 657 | * This function returns complete status |
647 | */ | 658 | */ |
648 | static int hw_test_and_clear_complete(int n) | 659 | static int hw_test_and_clear_complete(int n) |
649 | { | 660 | { |
661 | n = ep_to_bit(n); | ||
650 | return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n)); | 662 | return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n)); |
651 | } | 663 | } |
652 | 664 | ||
@@ -754,8 +766,11 @@ static ssize_t show_device(struct device *dev, struct device_attribute *attr, | |||
754 | 766 | ||
755 | n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n", | 767 | n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n", |
756 | gadget->speed); | 768 | gadget->speed); |
769 | n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n", | ||
770 | gadget->max_speed); | ||
771 | /* TODO: Scheduled for removal in 3.8. */ | ||
757 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n", | 772 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n", |
758 | gadget->is_dualspeed); | 773 | gadget_is_dualspeed(gadget)); |
759 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n", | 774 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n", |
760 | gadget->is_otg); | 775 | gadget->is_otg); |
761 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n", | 776 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n", |
@@ -798,7 +813,7 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr, | |||
798 | n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n", | 813 | n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n", |
799 | (driver->function ? driver->function : "")); | 814 | (driver->function ? driver->function : "")); |
800 | n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n", | 815 | n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n", |
801 | driver->speed); | 816 | driver->max_speed); |
802 | 817 | ||
803 | return n; | 818 | return n; |
804 | } | 819 | } |
@@ -2563,9 +2578,7 @@ static int ci13xxx_start(struct usb_gadget_driver *driver, | |||
2563 | if (driver == NULL || | 2578 | if (driver == NULL || |
2564 | bind == NULL || | 2579 | bind == NULL || |
2565 | driver->setup == NULL || | 2580 | driver->setup == NULL || |
2566 | driver->disconnect == NULL || | 2581 | driver->disconnect == NULL) |
2567 | driver->suspend == NULL || | ||
2568 | driver->resume == NULL) | ||
2569 | return -EINVAL; | 2582 | return -EINVAL; |
2570 | else if (udc == NULL) | 2583 | else if (udc == NULL) |
2571 | return -ENODEV; | 2584 | return -ENODEV; |
@@ -2693,8 +2706,6 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver) | |||
2693 | driver->unbind == NULL || | 2706 | driver->unbind == NULL || |
2694 | driver->setup == NULL || | 2707 | driver->setup == NULL || |
2695 | driver->disconnect == NULL || | 2708 | driver->disconnect == NULL || |
2696 | driver->suspend == NULL || | ||
2697 | driver->resume == NULL || | ||
2698 | driver != udc->driver) | 2709 | driver != udc->driver) |
2699 | return -EINVAL; | 2710 | return -EINVAL; |
2700 | 2711 | ||
@@ -2793,7 +2804,7 @@ static irqreturn_t udc_irq(void) | |||
2793 | isr_statistics.pci++; | 2804 | isr_statistics.pci++; |
2794 | udc->gadget.speed = hw_port_is_high_speed() ? | 2805 | udc->gadget.speed = hw_port_is_high_speed() ? |
2795 | USB_SPEED_HIGH : USB_SPEED_FULL; | 2806 | USB_SPEED_HIGH : USB_SPEED_FULL; |
2796 | if (udc->suspended) { | 2807 | if (udc->suspended && udc->driver->resume) { |
2797 | spin_unlock(udc->lock); | 2808 | spin_unlock(udc->lock); |
2798 | udc->driver->resume(&udc->gadget); | 2809 | udc->driver->resume(&udc->gadget); |
2799 | spin_lock(udc->lock); | 2810 | spin_lock(udc->lock); |
@@ -2807,7 +2818,8 @@ static irqreturn_t udc_irq(void) | |||
2807 | isr_tr_complete_handler(udc); | 2818 | isr_tr_complete_handler(udc); |
2808 | } | 2819 | } |
2809 | if (USBi_SLI & intr) { | 2820 | if (USBi_SLI & intr) { |
2810 | if (udc->gadget.speed != USB_SPEED_UNKNOWN) { | 2821 | if (udc->gadget.speed != USB_SPEED_UNKNOWN && |
2822 | udc->driver->suspend) { | ||
2811 | udc->suspended = 1; | 2823 | udc->suspended = 1; |
2812 | spin_unlock(udc->lock); | 2824 | spin_unlock(udc->lock); |
2813 | udc->driver->suspend(&udc->gadget); | 2825 | udc->driver->suspend(&udc->gadget); |
@@ -2871,7 +2883,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, | |||
2871 | 2883 | ||
2872 | udc->gadget.ops = &usb_gadget_ops; | 2884 | udc->gadget.ops = &usb_gadget_ops; |
2873 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 2885 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
2874 | udc->gadget.is_dualspeed = 1; | 2886 | udc->gadget.max_speed = USB_SPEED_HIGH; |
2875 | udc->gadget.is_otg = 0; | 2887 | udc->gadget.is_otg = 0; |
2876 | udc->gadget.name = driver->name; | 2888 | udc->gadget.name = driver->name; |
2877 | 2889 | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h index 23707775cb43..f4871e1fac59 100644 --- a/drivers/usb/gadget/ci13xxx_udc.h +++ b/drivers/usb/gadget/ci13xxx_udc.h | |||
@@ -127,7 +127,7 @@ struct ci13xxx { | |||
127 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ | 127 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ |
128 | u32 ep0_dir; /* ep0 direction */ | 128 | u32 ep0_dir; /* ep0 direction */ |
129 | #define ep0out ci13xxx_ep[0] | 129 | #define ep0out ci13xxx_ep[0] |
130 | #define ep0in ci13xxx_ep[16] | 130 | #define ep0in ci13xxx_ep[hw_ep_max / 2] |
131 | u8 remote_wakeup; /* Is remote wakeup feature | 131 | u8 remote_wakeup; /* Is remote wakeup feature |
132 | enabled by the host? */ | 132 | enabled by the host? */ |
133 | u8 suspended; /* suspended by the host */ | 133 | u8 suspended; /* suspended by the host */ |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f71b0787983f..a95de6a4a134 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -1535,9 +1535,9 @@ composite_resume(struct usb_gadget *gadget) | |||
1535 | 1535 | ||
1536 | static struct usb_gadget_driver composite_driver = { | 1536 | static struct usb_gadget_driver composite_driver = { |
1537 | #ifdef CONFIG_USB_GADGET_SUPERSPEED | 1537 | #ifdef CONFIG_USB_GADGET_SUPERSPEED |
1538 | .speed = USB_SPEED_SUPER, | 1538 | .max_speed = USB_SPEED_SUPER, |
1539 | #else | 1539 | #else |
1540 | .speed = USB_SPEED_HIGH, | 1540 | .max_speed = USB_SPEED_HIGH, |
1541 | #endif | 1541 | #endif |
1542 | 1542 | ||
1543 | .unbind = composite_unbind, | 1543 | .unbind = composite_unbind, |
@@ -1584,8 +1584,8 @@ int usb_composite_probe(struct usb_composite_driver *driver, | |||
1584 | driver->iProduct = driver->name; | 1584 | driver->iProduct = driver->name; |
1585 | composite_driver.function = (char *) driver->name; | 1585 | composite_driver.function = (char *) driver->name; |
1586 | composite_driver.driver.name = driver->name; | 1586 | composite_driver.driver.name = driver->name; |
1587 | composite_driver.speed = min((u8)composite_driver.speed, | 1587 | composite_driver.max_speed = |
1588 | (u8)driver->max_speed); | 1588 | min_t(u8, composite_driver.max_speed, driver->max_speed); |
1589 | composite = driver; | 1589 | composite = driver; |
1590 | composite_gadget_bind = bind; | 1590 | composite_gadget_bind = bind; |
1591 | 1591 | ||
diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c index 6256420089f3..19d7bb0df75a 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/dbgp.c | |||
@@ -404,7 +404,7 @@ fail: | |||
404 | 404 | ||
405 | static struct usb_gadget_driver dbgp_driver = { | 405 | static struct usb_gadget_driver dbgp_driver = { |
406 | .function = "dbgp", | 406 | .function = "dbgp", |
407 | .speed = USB_SPEED_HIGH, | 407 | .max_speed = USB_SPEED_HIGH, |
408 | .unbind = dbgp_unbind, | 408 | .unbind = dbgp_unbind, |
409 | .setup = dbgp_setup, | 409 | .setup = dbgp_setup, |
410 | .disconnect = dbgp_disconnect, | 410 | .disconnect = dbgp_disconnect, |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index ab8f1b488d54..db815c2da7ed 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -823,19 +823,18 @@ static int dummy_pullup (struct usb_gadget *_gadget, int value) | |||
823 | 823 | ||
824 | if (value && dum->driver) { | 824 | if (value && dum->driver) { |
825 | if (mod_data.is_super_speed) | 825 | if (mod_data.is_super_speed) |
826 | dum->gadget.speed = dum->driver->speed; | 826 | dum->gadget.speed = dum->driver->max_speed; |
827 | else if (mod_data.is_high_speed) | 827 | else if (mod_data.is_high_speed) |
828 | dum->gadget.speed = min_t(u8, USB_SPEED_HIGH, | 828 | dum->gadget.speed = min_t(u8, USB_SPEED_HIGH, |
829 | dum->driver->speed); | 829 | dum->driver->max_speed); |
830 | else | 830 | else |
831 | dum->gadget.speed = USB_SPEED_FULL; | 831 | dum->gadget.speed = USB_SPEED_FULL; |
832 | dummy_udc_udpate_ep0(dum); | 832 | dummy_udc_udpate_ep0(dum); |
833 | 833 | ||
834 | if (dum->gadget.speed < dum->driver->speed) | 834 | if (dum->gadget.speed < dum->driver->max_speed) |
835 | dev_dbg(udc_dev(dum), "This device can perform faster" | 835 | dev_dbg(udc_dev(dum), "This device can perform faster" |
836 | " if you connect it to a %s port...\n", | 836 | " if you connect it to a %s port...\n", |
837 | (dum->driver->speed == USB_SPEED_SUPER ? | 837 | usb_speed_string(dum->driver->max_speed)); |
838 | "SuperSpeed" : "HighSpeed")); | ||
839 | } | 838 | } |
840 | dum_hcd = gadget_to_dummy_hcd(_gadget); | 839 | dum_hcd = gadget_to_dummy_hcd(_gadget); |
841 | 840 | ||
@@ -898,7 +897,7 @@ static int dummy_udc_start(struct usb_gadget *g, | |||
898 | struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); | 897 | struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); |
899 | struct dummy *dum = dum_hcd->dum; | 898 | struct dummy *dum = dum_hcd->dum; |
900 | 899 | ||
901 | if (driver->speed == USB_SPEED_UNKNOWN) | 900 | if (driver->max_speed == USB_SPEED_UNKNOWN) |
902 | return -EINVAL; | 901 | return -EINVAL; |
903 | 902 | ||
904 | /* | 903 | /* |
@@ -977,7 +976,7 @@ static int dummy_udc_probe (struct platform_device *pdev) | |||
977 | 976 | ||
978 | dum->gadget.name = gadget_name; | 977 | dum->gadget.name = gadget_name; |
979 | dum->gadget.ops = &dummy_ops; | 978 | dum->gadget.ops = &dummy_ops; |
980 | dum->gadget.is_dualspeed = 1; | 979 | dum->gadget.max_speed = USB_SPEED_SUPER; |
981 | 980 | ||
982 | dev_set_name(&dum->gadget.dev, "gadget"); | 981 | dev_set_name(&dum->gadget.dev, "gadget"); |
983 | dum->gadget.dev.parent = &pdev->dev; | 982 | dum->gadget.dev.parent = &pdev->dev; |
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 4dff83d2f265..753aa0683ac1 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -149,7 +149,7 @@ ep_matches ( | |||
149 | switch (type) { | 149 | switch (type) { |
150 | case USB_ENDPOINT_XFER_INT: | 150 | case USB_ENDPOINT_XFER_INT: |
151 | /* INT: limit 64 bytes full speed, 1024 high/super speed */ | 151 | /* INT: limit 64 bytes full speed, 1024 high/super speed */ |
152 | if (!gadget->is_dualspeed && max > 64) | 152 | if (!gadget_is_dualspeed(gadget) && max > 64) |
153 | return 0; | 153 | return 0; |
154 | /* FALLTHROUGH */ | 154 | /* FALLTHROUGH */ |
155 | 155 | ||
@@ -157,12 +157,12 @@ ep_matches ( | |||
157 | /* ISO: limit 1023 bytes full speed, 1024 high/super speed */ | 157 | /* ISO: limit 1023 bytes full speed, 1024 high/super speed */ |
158 | if (ep->maxpacket < max) | 158 | if (ep->maxpacket < max) |
159 | return 0; | 159 | return 0; |
160 | if (!gadget->is_dualspeed && max > 1023) | 160 | if (!gadget_is_dualspeed(gadget) && max > 1023) |
161 | return 0; | 161 | return 0; |
162 | 162 | ||
163 | /* BOTH: "high bandwidth" works only at high speed */ | 163 | /* BOTH: "high bandwidth" works only at high speed */ |
164 | if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) { | 164 | if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) { |
165 | if (!gadget->is_dualspeed) | 165 | if (!gadget_is_dualspeed(gadget)) |
166 | return 0; | 166 | return 0; |
167 | /* configure your hardware with enough buffering!! */ | 167 | /* configure your hardware with enough buffering!! */ |
168 | } | 168 | } |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index b5f6f9fef9c7..f63dc6c150d2 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -1399,7 +1399,7 @@ static int ffs_epfiles_create(struct ffs_data *ffs) | |||
1399 | ENTER(); | 1399 | ENTER(); |
1400 | 1400 | ||
1401 | count = ffs->eps_count; | 1401 | count = ffs->eps_count; |
1402 | epfiles = kzalloc(count * sizeof *epfiles, GFP_KERNEL); | 1402 | epfiles = kcalloc(count, sizeof(*epfiles), GFP_KERNEL); |
1403 | if (!epfiles) | 1403 | if (!epfiles) |
1404 | return -ENOMEM; | 1404 | return -ENOMEM; |
1405 | 1405 | ||
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 1a6f415c0d02..6353eca1e852 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -1873,17 +1873,14 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
1873 | common->lun, lun); | 1873 | common->lun, lun); |
1874 | 1874 | ||
1875 | /* Check the LUN */ | 1875 | /* Check the LUN */ |
1876 | if (common->lun < common->nluns) { | 1876 | curlun = common->curlun; |
1877 | curlun = &common->luns[common->lun]; | 1877 | if (curlun) { |
1878 | common->curlun = curlun; | ||
1879 | if (common->cmnd[0] != REQUEST_SENSE) { | 1878 | if (common->cmnd[0] != REQUEST_SENSE) { |
1880 | curlun->sense_data = SS_NO_SENSE; | 1879 | curlun->sense_data = SS_NO_SENSE; |
1881 | curlun->sense_data_info = 0; | 1880 | curlun->sense_data_info = 0; |
1882 | curlun->info_valid = 0; | 1881 | curlun->info_valid = 0; |
1883 | } | 1882 | } |
1884 | } else { | 1883 | } else { |
1885 | common->curlun = NULL; | ||
1886 | curlun = NULL; | ||
1887 | common->bad_lun_okay = 0; | 1884 | common->bad_lun_okay = 0; |
1888 | 1885 | ||
1889 | /* | 1886 | /* |
@@ -1929,6 +1926,17 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
1929 | return 0; | 1926 | return 0; |
1930 | } | 1927 | } |
1931 | 1928 | ||
1929 | /* wrapper of check_command for data size in blocks handling */ | ||
1930 | static int check_command_size_in_blocks(struct fsg_common *common, | ||
1931 | int cmnd_size, enum data_direction data_dir, | ||
1932 | unsigned int mask, int needs_medium, const char *name) | ||
1933 | { | ||
1934 | if (common->curlun) | ||
1935 | common->data_size_from_cmnd <<= common->curlun->blkbits; | ||
1936 | return check_command(common, cmnd_size, data_dir, | ||
1937 | mask, needs_medium, name); | ||
1938 | } | ||
1939 | |||
1932 | static int do_scsi_command(struct fsg_common *common) | 1940 | static int do_scsi_command(struct fsg_common *common) |
1933 | { | 1941 | { |
1934 | struct fsg_buffhd *bh; | 1942 | struct fsg_buffhd *bh; |
@@ -2011,9 +2019,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2011 | 2019 | ||
2012 | case READ_6: | 2020 | case READ_6: |
2013 | i = common->cmnd[4]; | 2021 | i = common->cmnd[4]; |
2014 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << | 2022 | common->data_size_from_cmnd = (i == 0) ? 256 : i; |
2015 | common->curlun->blkbits; | 2023 | reply = check_command_size_in_blocks(common, 6, |
2016 | reply = check_command(common, 6, DATA_DIR_TO_HOST, | 2024 | DATA_DIR_TO_HOST, |
2017 | (7<<1) | (1<<4), 1, | 2025 | (7<<1) | (1<<4), 1, |
2018 | "READ(6)"); | 2026 | "READ(6)"); |
2019 | if (reply == 0) | 2027 | if (reply == 0) |
@@ -2022,9 +2030,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2022 | 2030 | ||
2023 | case READ_10: | 2031 | case READ_10: |
2024 | common->data_size_from_cmnd = | 2032 | common->data_size_from_cmnd = |
2025 | get_unaligned_be16(&common->cmnd[7]) << | 2033 | get_unaligned_be16(&common->cmnd[7]); |
2026 | common->curlun->blkbits; | 2034 | reply = check_command_size_in_blocks(common, 10, |
2027 | reply = check_command(common, 10, DATA_DIR_TO_HOST, | 2035 | DATA_DIR_TO_HOST, |
2028 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2036 | (1<<1) | (0xf<<2) | (3<<7), 1, |
2029 | "READ(10)"); | 2037 | "READ(10)"); |
2030 | if (reply == 0) | 2038 | if (reply == 0) |
@@ -2033,9 +2041,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2033 | 2041 | ||
2034 | case READ_12: | 2042 | case READ_12: |
2035 | common->data_size_from_cmnd = | 2043 | common->data_size_from_cmnd = |
2036 | get_unaligned_be32(&common->cmnd[6]) << | 2044 | get_unaligned_be32(&common->cmnd[6]); |
2037 | common->curlun->blkbits; | 2045 | reply = check_command_size_in_blocks(common, 12, |
2038 | reply = check_command(common, 12, DATA_DIR_TO_HOST, | 2046 | DATA_DIR_TO_HOST, |
2039 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2047 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
2040 | "READ(12)"); | 2048 | "READ(12)"); |
2041 | if (reply == 0) | 2049 | if (reply == 0) |
@@ -2134,9 +2142,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2134 | 2142 | ||
2135 | case WRITE_6: | 2143 | case WRITE_6: |
2136 | i = common->cmnd[4]; | 2144 | i = common->cmnd[4]; |
2137 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << | 2145 | common->data_size_from_cmnd = (i == 0) ? 256 : i; |
2138 | common->curlun->blkbits; | 2146 | reply = check_command_size_in_blocks(common, 6, |
2139 | reply = check_command(common, 6, DATA_DIR_FROM_HOST, | 2147 | DATA_DIR_FROM_HOST, |
2140 | (7<<1) | (1<<4), 1, | 2148 | (7<<1) | (1<<4), 1, |
2141 | "WRITE(6)"); | 2149 | "WRITE(6)"); |
2142 | if (reply == 0) | 2150 | if (reply == 0) |
@@ -2145,9 +2153,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2145 | 2153 | ||
2146 | case WRITE_10: | 2154 | case WRITE_10: |
2147 | common->data_size_from_cmnd = | 2155 | common->data_size_from_cmnd = |
2148 | get_unaligned_be16(&common->cmnd[7]) << | 2156 | get_unaligned_be16(&common->cmnd[7]); |
2149 | common->curlun->blkbits; | 2157 | reply = check_command_size_in_blocks(common, 10, |
2150 | reply = check_command(common, 10, DATA_DIR_FROM_HOST, | 2158 | DATA_DIR_FROM_HOST, |
2151 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2159 | (1<<1) | (0xf<<2) | (3<<7), 1, |
2152 | "WRITE(10)"); | 2160 | "WRITE(10)"); |
2153 | if (reply == 0) | 2161 | if (reply == 0) |
@@ -2156,9 +2164,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2156 | 2164 | ||
2157 | case WRITE_12: | 2165 | case WRITE_12: |
2158 | common->data_size_from_cmnd = | 2166 | common->data_size_from_cmnd = |
2159 | get_unaligned_be32(&common->cmnd[6]) << | 2167 | get_unaligned_be32(&common->cmnd[6]); |
2160 | common->curlun->blkbits; | 2168 | reply = check_command_size_in_blocks(common, 12, |
2161 | reply = check_command(common, 12, DATA_DIR_FROM_HOST, | 2169 | DATA_DIR_FROM_HOST, |
2162 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2170 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
2163 | "WRITE(12)"); | 2171 | "WRITE(12)"); |
2164 | if (reply == 0) | 2172 | if (reply == 0) |
@@ -2273,6 +2281,10 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
2273 | if (common->data_size == 0) | 2281 | if (common->data_size == 0) |
2274 | common->data_dir = DATA_DIR_NONE; | 2282 | common->data_dir = DATA_DIR_NONE; |
2275 | common->lun = cbw->Lun; | 2283 | common->lun = cbw->Lun; |
2284 | if (common->lun >= 0 && common->lun < common->nluns) | ||
2285 | common->curlun = &common->luns[common->lun]; | ||
2286 | else | ||
2287 | common->curlun = NULL; | ||
2276 | common->tag = cbw->Tag; | 2288 | common->tag = cbw->Tag; |
2277 | return 0; | 2289 | return 0; |
2278 | } | 2290 | } |
@@ -2763,7 +2775,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2763 | * Create the LUNs, open their backing files, and register the | 2775 | * Create the LUNs, open their backing files, and register the |
2764 | * LUN devices in sysfs. | 2776 | * LUN devices in sysfs. |
2765 | */ | 2777 | */ |
2766 | curlun = kzalloc(nluns * sizeof *curlun, GFP_KERNEL); | 2778 | curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL); |
2767 | if (unlikely(!curlun)) { | 2779 | if (unlikely(!curlun)) { |
2768 | rc = -ENOMEM; | 2780 | rc = -ENOMEM; |
2769 | goto error_release; | 2781 | goto error_release; |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 11b5196284ae..e0f30fc70e45 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -2297,19 +2297,17 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, | |||
2297 | DBG(fsg, "using LUN %d from CBW, " | 2297 | DBG(fsg, "using LUN %d from CBW, " |
2298 | "not LUN %d from CDB\n", | 2298 | "not LUN %d from CDB\n", |
2299 | fsg->lun, lun); | 2299 | fsg->lun, lun); |
2300 | } else | 2300 | } |
2301 | fsg->lun = lun; // Use LUN from the command | ||
2302 | 2301 | ||
2303 | /* Check the LUN */ | 2302 | /* Check the LUN */ |
2304 | if (fsg->lun < fsg->nluns) { | 2303 | curlun = fsg->curlun; |
2305 | fsg->curlun = curlun = &fsg->luns[fsg->lun]; | 2304 | if (curlun) { |
2306 | if (fsg->cmnd[0] != REQUEST_SENSE) { | 2305 | if (fsg->cmnd[0] != REQUEST_SENSE) { |
2307 | curlun->sense_data = SS_NO_SENSE; | 2306 | curlun->sense_data = SS_NO_SENSE; |
2308 | curlun->sense_data_info = 0; | 2307 | curlun->sense_data_info = 0; |
2309 | curlun->info_valid = 0; | 2308 | curlun->info_valid = 0; |
2310 | } | 2309 | } |
2311 | } else { | 2310 | } else { |
2312 | fsg->curlun = curlun = NULL; | ||
2313 | fsg->bad_lun_okay = 0; | 2311 | fsg->bad_lun_okay = 0; |
2314 | 2312 | ||
2315 | /* INQUIRY and REQUEST SENSE commands are explicitly allowed | 2313 | /* INQUIRY and REQUEST SENSE commands are explicitly allowed |
@@ -2351,6 +2349,16 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, | |||
2351 | return 0; | 2349 | return 0; |
2352 | } | 2350 | } |
2353 | 2351 | ||
2352 | /* wrapper of check_command for data size in blocks handling */ | ||
2353 | static int check_command_size_in_blocks(struct fsg_dev *fsg, int cmnd_size, | ||
2354 | enum data_direction data_dir, unsigned int mask, | ||
2355 | int needs_medium, const char *name) | ||
2356 | { | ||
2357 | if (fsg->curlun) | ||
2358 | fsg->data_size_from_cmnd <<= fsg->curlun->blkbits; | ||
2359 | return check_command(fsg, cmnd_size, data_dir, | ||
2360 | mask, needs_medium, name); | ||
2361 | } | ||
2354 | 2362 | ||
2355 | static int do_scsi_command(struct fsg_dev *fsg) | 2363 | static int do_scsi_command(struct fsg_dev *fsg) |
2356 | { | 2364 | { |
@@ -2425,26 +2433,27 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
2425 | 2433 | ||
2426 | case READ_6: | 2434 | case READ_6: |
2427 | i = fsg->cmnd[4]; | 2435 | i = fsg->cmnd[4]; |
2428 | fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits; | 2436 | fsg->data_size_from_cmnd = (i == 0) ? 256 : i; |
2429 | if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, | 2437 | if ((reply = check_command_size_in_blocks(fsg, 6, |
2438 | DATA_DIR_TO_HOST, | ||
2430 | (7<<1) | (1<<4), 1, | 2439 | (7<<1) | (1<<4), 1, |
2431 | "READ(6)")) == 0) | 2440 | "READ(6)")) == 0) |
2432 | reply = do_read(fsg); | 2441 | reply = do_read(fsg); |
2433 | break; | 2442 | break; |
2434 | 2443 | ||
2435 | case READ_10: | 2444 | case READ_10: |
2436 | fsg->data_size_from_cmnd = | 2445 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); |
2437 | get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits; | 2446 | if ((reply = check_command_size_in_blocks(fsg, 10, |
2438 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | 2447 | DATA_DIR_TO_HOST, |
2439 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2448 | (1<<1) | (0xf<<2) | (3<<7), 1, |
2440 | "READ(10)")) == 0) | 2449 | "READ(10)")) == 0) |
2441 | reply = do_read(fsg); | 2450 | reply = do_read(fsg); |
2442 | break; | 2451 | break; |
2443 | 2452 | ||
2444 | case READ_12: | 2453 | case READ_12: |
2445 | fsg->data_size_from_cmnd = | 2454 | fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]); |
2446 | get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits; | 2455 | if ((reply = check_command_size_in_blocks(fsg, 12, |
2447 | if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST, | 2456 | DATA_DIR_TO_HOST, |
2448 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2457 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
2449 | "READ(12)")) == 0) | 2458 | "READ(12)")) == 0) |
2450 | reply = do_read(fsg); | 2459 | reply = do_read(fsg); |
@@ -2529,26 +2538,27 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
2529 | 2538 | ||
2530 | case WRITE_6: | 2539 | case WRITE_6: |
2531 | i = fsg->cmnd[4]; | 2540 | i = fsg->cmnd[4]; |
2532 | fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits; | 2541 | fsg->data_size_from_cmnd = (i == 0) ? 256 : i; |
2533 | if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, | 2542 | if ((reply = check_command_size_in_blocks(fsg, 6, |
2543 | DATA_DIR_FROM_HOST, | ||
2534 | (7<<1) | (1<<4), 1, | 2544 | (7<<1) | (1<<4), 1, |
2535 | "WRITE(6)")) == 0) | 2545 | "WRITE(6)")) == 0) |
2536 | reply = do_write(fsg); | 2546 | reply = do_write(fsg); |
2537 | break; | 2547 | break; |
2538 | 2548 | ||
2539 | case WRITE_10: | 2549 | case WRITE_10: |
2540 | fsg->data_size_from_cmnd = | 2550 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); |
2541 | get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits; | 2551 | if ((reply = check_command_size_in_blocks(fsg, 10, |
2542 | if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, | 2552 | DATA_DIR_FROM_HOST, |
2543 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2553 | (1<<1) | (0xf<<2) | (3<<7), 1, |
2544 | "WRITE(10)")) == 0) | 2554 | "WRITE(10)")) == 0) |
2545 | reply = do_write(fsg); | 2555 | reply = do_write(fsg); |
2546 | break; | 2556 | break; |
2547 | 2557 | ||
2548 | case WRITE_12: | 2558 | case WRITE_12: |
2549 | fsg->data_size_from_cmnd = | 2559 | fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]); |
2550 | get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits; | 2560 | if ((reply = check_command_size_in_blocks(fsg, 12, |
2551 | if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST, | 2561 | DATA_DIR_FROM_HOST, |
2552 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2562 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
2553 | "WRITE(12)")) == 0) | 2563 | "WRITE(12)")) == 0) |
2554 | reply = do_write(fsg); | 2564 | reply = do_write(fsg); |
@@ -2715,7 +2725,17 @@ static int get_next_command(struct fsg_dev *fsg) | |||
2715 | memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size); | 2725 | memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size); |
2716 | fsg->cbbuf_cmnd_size = 0; | 2726 | fsg->cbbuf_cmnd_size = 0; |
2717 | spin_unlock_irq(&fsg->lock); | 2727 | spin_unlock_irq(&fsg->lock); |
2728 | |||
2729 | /* Use LUN from the command */ | ||
2730 | fsg->lun = fsg->cmnd[1] >> 5; | ||
2718 | } | 2731 | } |
2732 | |||
2733 | /* Update current lun */ | ||
2734 | if (fsg->lun >= 0 && fsg->lun < fsg->nluns) | ||
2735 | fsg->curlun = &fsg->luns[fsg->lun]; | ||
2736 | else | ||
2737 | fsg->curlun = NULL; | ||
2738 | |||
2719 | return rc; | 2739 | return rc; |
2720 | } | 2740 | } |
2721 | 2741 | ||
@@ -3584,7 +3604,7 @@ static void fsg_resume(struct usb_gadget *gadget) | |||
3584 | /*-------------------------------------------------------------------------*/ | 3604 | /*-------------------------------------------------------------------------*/ |
3585 | 3605 | ||
3586 | static struct usb_gadget_driver fsg_driver = { | 3606 | static struct usb_gadget_driver fsg_driver = { |
3587 | .speed = USB_SPEED_SUPER, | 3607 | .max_speed = USB_SPEED_SUPER, |
3588 | .function = (char *) fsg_string_product, | 3608 | .function = (char *) fsg_string_product, |
3589 | .unbind = fsg_unbind, | 3609 | .unbind = fsg_unbind, |
3590 | .disconnect = fsg_disconnect, | 3610 | .disconnect = fsg_disconnect, |
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index e00cf92409ce..b95697c03d07 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
@@ -2336,7 +2336,7 @@ static int fsl_qe_start(struct usb_gadget_driver *driver, | |||
2336 | if (!udc_controller) | 2336 | if (!udc_controller) |
2337 | return -ENODEV; | 2337 | return -ENODEV; |
2338 | 2338 | ||
2339 | if (!driver || driver->speed < USB_SPEED_FULL | 2339 | if (!driver || driver->max_speed < USB_SPEED_FULL |
2340 | || !bind || !driver->disconnect || !driver->setup) | 2340 | || !bind || !driver->disconnect || !driver->setup) |
2341 | return -EINVAL; | 2341 | return -EINVAL; |
2342 | 2342 | ||
@@ -2350,7 +2350,7 @@ static int fsl_qe_start(struct usb_gadget_driver *driver, | |||
2350 | /* hook up the driver */ | 2350 | /* hook up the driver */ |
2351 | udc_controller->driver = driver; | 2351 | udc_controller->driver = driver; |
2352 | udc_controller->gadget.dev.driver = &driver->driver; | 2352 | udc_controller->gadget.dev.driver = &driver->driver; |
2353 | udc_controller->gadget.speed = (enum usb_device_speed)(driver->speed); | 2353 | udc_controller->gadget.speed = driver->max_speed; |
2354 | spin_unlock_irqrestore(&udc_controller->lock, flags); | 2354 | spin_unlock_irqrestore(&udc_controller->lock, flags); |
2355 | 2355 | ||
2356 | retval = bind(&udc_controller->gadget); | 2356 | retval = bind(&udc_controller->gadget); |
@@ -2814,20 +2814,7 @@ static struct platform_driver udc_driver = { | |||
2814 | #endif | 2814 | #endif |
2815 | }; | 2815 | }; |
2816 | 2816 | ||
2817 | static int __init qe_udc_init(void) | 2817 | module_platform_driver(udc_driver); |
2818 | { | ||
2819 | printk(KERN_INFO "%s: %s, %s\n", driver_name, driver_desc, | ||
2820 | DRIVER_VERSION); | ||
2821 | return platform_driver_register(&udc_driver); | ||
2822 | } | ||
2823 | |||
2824 | static void __exit qe_udc_exit(void) | ||
2825 | { | ||
2826 | platform_driver_unregister(&udc_driver); | ||
2827 | } | ||
2828 | |||
2829 | module_init(qe_udc_init); | ||
2830 | module_exit(qe_udc_exit); | ||
2831 | 2818 | ||
2832 | MODULE_DESCRIPTION(DRIVER_DESC); | 2819 | MODULE_DESCRIPTION(DRIVER_DESC); |
2833 | MODULE_AUTHOR(DRIVER_AUTHOR); | 2820 | MODULE_AUTHOR(DRIVER_AUTHOR); |
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index dd28ef3def71..d7ea6c076ce9 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
@@ -1934,7 +1934,7 @@ static int fsl_start(struct usb_gadget_driver *driver, | |||
1934 | if (!udc_controller) | 1934 | if (!udc_controller) |
1935 | return -ENODEV; | 1935 | return -ENODEV; |
1936 | 1936 | ||
1937 | if (!driver || driver->speed < USB_SPEED_FULL | 1937 | if (!driver || driver->max_speed < USB_SPEED_FULL |
1938 | || !bind || !driver->disconnect || !driver->setup) | 1938 | || !bind || !driver->disconnect || !driver->setup) |
1939 | return -EINVAL; | 1939 | return -EINVAL; |
1940 | 1940 | ||
@@ -2525,7 +2525,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2525 | 2525 | ||
2526 | /* Setup gadget structure */ | 2526 | /* Setup gadget structure */ |
2527 | udc_controller->gadget.ops = &fsl_gadget_ops; | 2527 | udc_controller->gadget.ops = &fsl_gadget_ops; |
2528 | udc_controller->gadget.is_dualspeed = 1; | 2528 | udc_controller->gadget.max_speed = USB_SPEED_HIGH; |
2529 | udc_controller->gadget.ep0 = &udc_controller->eps[0].ep; | 2529 | udc_controller->gadget.ep0 = &udc_controller->eps[0].ep; |
2530 | INIT_LIST_HEAD(&udc_controller->gadget.ep_list); | 2530 | INIT_LIST_HEAD(&udc_controller->gadget.ep_list); |
2531 | udc_controller->gadget.speed = USB_SPEED_UNKNOWN; | 2531 | udc_controller->gadget.speed = USB_SPEED_UNKNOWN; |
diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index 74da206c8406..5831cb4a0b35 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c | |||
@@ -1317,7 +1317,7 @@ static int fusb300_udc_start(struct usb_gadget_driver *driver, | |||
1317 | int retval; | 1317 | int retval; |
1318 | 1318 | ||
1319 | if (!driver | 1319 | if (!driver |
1320 | || driver->speed < USB_SPEED_FULL | 1320 | || driver->max_speed < USB_SPEED_FULL |
1321 | || !bind | 1321 | || !bind |
1322 | || !driver->setup) | 1322 | || !driver->setup) |
1323 | return -EINVAL; | 1323 | return -EINVAL; |
@@ -1463,7 +1463,7 @@ static int __init fusb300_probe(struct platform_device *pdev) | |||
1463 | 1463 | ||
1464 | dev_set_name(&fusb300->gadget.dev, "gadget"); | 1464 | dev_set_name(&fusb300->gadget.dev, "gadget"); |
1465 | 1465 | ||
1466 | fusb300->gadget.is_dualspeed = 1; | 1466 | fusb300->gadget.max_speed = USB_SPEED_HIGH; |
1467 | fusb300->gadget.dev.parent = &pdev->dev; | 1467 | fusb300->gadget.dev.parent = &pdev->dev; |
1468 | fusb300->gadget.dev.dma_mask = pdev->dev.dma_mask; | 1468 | fusb300->gadget.dev.dma_mask = pdev->dev.dma_mask; |
1469 | fusb300->gadget.dev.release = pdev->dev.release; | 1469 | fusb300->gadget.dev.release = pdev->dev.release; |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 7f87805cddc4..5af70fcce139 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1357,7 +1357,7 @@ static int goku_start(struct usb_gadget_driver *driver, | |||
1357 | int retval; | 1357 | int retval; |
1358 | 1358 | ||
1359 | if (!driver | 1359 | if (!driver |
1360 | || driver->speed < USB_SPEED_FULL | 1360 | || driver->max_speed < USB_SPEED_FULL |
1361 | || !bind | 1361 | || !bind |
1362 | || !driver->disconnect | 1362 | || !driver->disconnect |
1363 | || !driver->setup) | 1363 | || !driver->setup) |
@@ -1796,6 +1796,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1796 | spin_lock_init(&dev->lock); | 1796 | spin_lock_init(&dev->lock); |
1797 | dev->pdev = pdev; | 1797 | dev->pdev = pdev; |
1798 | dev->gadget.ops = &goku_ops; | 1798 | dev->gadget.ops = &goku_ops; |
1799 | dev->gadget.max_speed = USB_SPEED_FULL; | ||
1799 | 1800 | ||
1800 | /* the "gadget" abstracts/virtualizes the controller */ | 1801 | /* the "gadget" abstracts/virtualizes the controller */ |
1801 | dev_set_name(&dev->gadget.dev, "gadget"); | 1802 | dev_set_name(&dev->gadget.dev, "gadget"); |
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 2d978c0e7ced..8d1c75abd73d 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c | |||
@@ -1336,7 +1336,7 @@ static int imx_udc_start(struct usb_gadget_driver *driver, | |||
1336 | int retval; | 1336 | int retval; |
1337 | 1337 | ||
1338 | if (!driver | 1338 | if (!driver |
1339 | || driver->speed < USB_SPEED_FULL | 1339 | || driver->max_speed < USB_SPEED_FULL |
1340 | || !bind | 1340 | || !bind |
1341 | || !driver->disconnect | 1341 | || !driver->disconnect |
1342 | || !driver->setup) | 1342 | || !driver->setup) |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 6b7ea25af0fe..ae04266dba1b 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -1766,9 +1766,9 @@ gadgetfs_suspend (struct usb_gadget *gadget) | |||
1766 | 1766 | ||
1767 | static struct usb_gadget_driver gadgetfs_driver = { | 1767 | static struct usb_gadget_driver gadgetfs_driver = { |
1768 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1768 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1769 | .speed = USB_SPEED_HIGH, | 1769 | .max_speed = USB_SPEED_HIGH, |
1770 | #else | 1770 | #else |
1771 | .speed = USB_SPEED_FULL, | 1771 | .max_speed = USB_SPEED_FULL, |
1772 | #endif | 1772 | #endif |
1773 | .function = (char *) driver_desc, | 1773 | .function = (char *) driver_desc, |
1774 | .unbind = gadgetfs_unbind, | 1774 | .unbind = gadgetfs_unbind, |
@@ -1792,7 +1792,7 @@ static int gadgetfs_probe (struct usb_gadget *gadget) | |||
1792 | } | 1792 | } |
1793 | 1793 | ||
1794 | static struct usb_gadget_driver probe_driver = { | 1794 | static struct usb_gadget_driver probe_driver = { |
1795 | .speed = USB_SPEED_HIGH, | 1795 | .max_speed = USB_SPEED_HIGH, |
1796 | .unbind = gadgetfs_nop, | 1796 | .unbind = gadgetfs_nop, |
1797 | .setup = (void *)gadgetfs_nop, | 1797 | .setup = (void *)gadgetfs_nop, |
1798 | .disconnect = gadgetfs_nop, | 1798 | .disconnect = gadgetfs_nop, |
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index c9fa3bf5b377..fa0fcc11263f 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c | |||
@@ -3267,7 +3267,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, | |||
3267 | dev->gadget.ep0 = &dev->ep[0].ep; /* gadget ep0 */ | 3267 | dev->gadget.ep0 = &dev->ep[0].ep; /* gadget ep0 */ |
3268 | INIT_LIST_HEAD(&dev->gadget.ep_list); /* ep_list */ | 3268 | INIT_LIST_HEAD(&dev->gadget.ep_list); /* ep_list */ |
3269 | dev->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ | 3269 | dev->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ |
3270 | dev->gadget.is_dualspeed = 1; /* support dual speed */ | 3270 | dev->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */ |
3271 | #ifdef OTG_TRANSCEIVER | 3271 | #ifdef OTG_TRANSCEIVER |
3272 | dev->gadget.is_otg = 1; /* support otg mode */ | 3272 | dev->gadget.is_otg = 1; /* support otg mode */ |
3273 | #endif | 3273 | #endif |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 9aa1cbbee45b..3608b3bd5732 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -1472,7 +1472,7 @@ static int m66592_start(struct usb_gadget_driver *driver, | |||
1472 | int retval; | 1472 | int retval; |
1473 | 1473 | ||
1474 | if (!driver | 1474 | if (!driver |
1475 | || driver->speed < USB_SPEED_HIGH | 1475 | || driver->max_speed < USB_SPEED_HIGH |
1476 | || !bind | 1476 | || !bind |
1477 | || !driver->setup) | 1477 | || !driver->setup) |
1478 | return -EINVAL; | 1478 | return -EINVAL; |
@@ -1653,7 +1653,7 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1653 | m66592->gadget.ops = &m66592_gadget_ops; | 1653 | m66592->gadget.ops = &m66592_gadget_ops; |
1654 | device_initialize(&m66592->gadget.dev); | 1654 | device_initialize(&m66592->gadget.dev); |
1655 | dev_set_name(&m66592->gadget.dev, "gadget"); | 1655 | dev_set_name(&m66592->gadget.dev, "gadget"); |
1656 | m66592->gadget.is_dualspeed = 1; | 1656 | m66592->gadget.max_speed = USB_SPEED_HIGH; |
1657 | m66592->gadget.dev.parent = &pdev->dev; | 1657 | m66592->gadget.dev.parent = &pdev->dev; |
1658 | m66592->gadget.dev.dma_mask = pdev->dev.dma_mask; | 1658 | m66592->gadget.dev.dma_mask = pdev->dev.dma_mask; |
1659 | m66592->gadget.dev.release = pdev->dev.release; | 1659 | m66592->gadget.dev.release = pdev->dev.release; |
diff --git a/drivers/usb/gadget/mv_udc.h b/drivers/usb/gadget/mv_udc.h index daa75c12f336..34aadfae723d 100644 --- a/drivers/usb/gadget/mv_udc.h +++ b/drivers/usb/gadget/mv_udc.h | |||
@@ -180,7 +180,7 @@ struct mv_udc { | |||
180 | 180 | ||
181 | struct mv_cap_regs __iomem *cap_regs; | 181 | struct mv_cap_regs __iomem *cap_regs; |
182 | struct mv_op_regs __iomem *op_regs; | 182 | struct mv_op_regs __iomem *op_regs; |
183 | unsigned int phy_regs; | 183 | void __iomem *phy_regs; |
184 | unsigned int max_eps; | 184 | unsigned int max_eps; |
185 | struct mv_dqh *ep_dqh; | 185 | struct mv_dqh *ep_dqh; |
186 | size_t ep_dqh_size; | 186 | size_t ep_dqh_size; |
@@ -211,11 +211,14 @@ struct mv_udc { | |||
211 | softconnected:1, | 211 | softconnected:1, |
212 | force_fs:1, | 212 | force_fs:1, |
213 | clock_gating:1, | 213 | clock_gating:1, |
214 | active:1; | 214 | active:1, |
215 | stopped:1; /* stop bit is setted */ | ||
215 | 216 | ||
216 | struct work_struct vbus_work; | 217 | struct work_struct vbus_work; |
217 | struct workqueue_struct *qwork; | 218 | struct workqueue_struct *qwork; |
218 | 219 | ||
220 | struct otg_transceiver *transceiver; | ||
221 | |||
219 | struct mv_usb_platform_data *pdata; | 222 | struct mv_usb_platform_data *pdata; |
220 | 223 | ||
221 | /* some SOC has mutiple clock sources for USB*/ | 224 | /* some SOC has mutiple clock sources for USB*/ |
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 892412103dd8..f97e737d26f7 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c | |||
@@ -276,11 +276,12 @@ static void done(struct mv_ep *ep, struct mv_req *req, int status) | |||
276 | 276 | ||
277 | static int queue_dtd(struct mv_ep *ep, struct mv_req *req) | 277 | static int queue_dtd(struct mv_ep *ep, struct mv_req *req) |
278 | { | 278 | { |
279 | u32 tmp, epstatus, bit_pos, direction; | ||
280 | struct mv_udc *udc; | 279 | struct mv_udc *udc; |
281 | struct mv_dqh *dqh; | 280 | struct mv_dqh *dqh; |
281 | u32 bit_pos, direction; | ||
282 | u32 usbcmd, epstatus; | ||
282 | unsigned int loops; | 283 | unsigned int loops; |
283 | int readsafe, retval = 0; | 284 | int retval = 0; |
284 | 285 | ||
285 | udc = ep->udc; | 286 | udc = ep->udc; |
286 | direction = ep_dir(ep); | 287 | direction = ep_dir(ep); |
@@ -293,30 +294,18 @@ static int queue_dtd(struct mv_ep *ep, struct mv_req *req) | |||
293 | lastreq = list_entry(ep->queue.prev, struct mv_req, queue); | 294 | lastreq = list_entry(ep->queue.prev, struct mv_req, queue); |
294 | lastreq->tail->dtd_next = | 295 | lastreq->tail->dtd_next = |
295 | req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK; | 296 | req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK; |
296 | if (readl(&udc->op_regs->epprime) & bit_pos) { | 297 | |
297 | loops = LOOPS(PRIME_TIMEOUT); | 298 | wmb(); |
298 | while (readl(&udc->op_regs->epprime) & bit_pos) { | 299 | |
299 | if (loops == 0) { | 300 | if (readl(&udc->op_regs->epprime) & bit_pos) |
300 | retval = -ETIME; | 301 | goto done; |
301 | goto done; | 302 | |
302 | } | ||
303 | udelay(LOOPS_USEC); | ||
304 | loops--; | ||
305 | } | ||
306 | if (readl(&udc->op_regs->epstatus) & bit_pos) | ||
307 | goto done; | ||
308 | } | ||
309 | readsafe = 0; | ||
310 | loops = LOOPS(READSAFE_TIMEOUT); | 303 | loops = LOOPS(READSAFE_TIMEOUT); |
311 | while (readsafe == 0) { | 304 | while (1) { |
312 | if (loops == 0) { | ||
313 | retval = -ETIME; | ||
314 | goto done; | ||
315 | } | ||
316 | /* start with setting the semaphores */ | 305 | /* start with setting the semaphores */ |
317 | tmp = readl(&udc->op_regs->usbcmd); | 306 | usbcmd = readl(&udc->op_regs->usbcmd); |
318 | tmp |= USBCMD_ATDTW_TRIPWIRE_SET; | 307 | usbcmd |= USBCMD_ATDTW_TRIPWIRE_SET; |
319 | writel(tmp, &udc->op_regs->usbcmd); | 308 | writel(usbcmd, &udc->op_regs->usbcmd); |
320 | 309 | ||
321 | /* read the endpoint status */ | 310 | /* read the endpoint status */ |
322 | epstatus = readl(&udc->op_regs->epstatus) & bit_pos; | 311 | epstatus = readl(&udc->op_regs->epstatus) & bit_pos; |
@@ -329,98 +318,46 @@ static int queue_dtd(struct mv_ep *ep, struct mv_req *req) | |||
329 | * primed. | 318 | * primed. |
330 | */ | 319 | */ |
331 | if (readl(&udc->op_regs->usbcmd) | 320 | if (readl(&udc->op_regs->usbcmd) |
332 | & USBCMD_ATDTW_TRIPWIRE_SET) { | 321 | & USBCMD_ATDTW_TRIPWIRE_SET) |
333 | readsafe = 1; | 322 | break; |
334 | } | 323 | |
335 | loops--; | 324 | loops--; |
325 | if (loops == 0) { | ||
326 | dev_err(&udc->dev->dev, | ||
327 | "Timeout for ATDTW_TRIPWIRE...\n"); | ||
328 | retval = -ETIME; | ||
329 | goto done; | ||
330 | } | ||
336 | udelay(LOOPS_USEC); | 331 | udelay(LOOPS_USEC); |
337 | } | 332 | } |
338 | 333 | ||
339 | /* Clear the semaphore */ | 334 | /* Clear the semaphore */ |
340 | tmp = readl(&udc->op_regs->usbcmd); | 335 | usbcmd = readl(&udc->op_regs->usbcmd); |
341 | tmp &= USBCMD_ATDTW_TRIPWIRE_CLEAR; | 336 | usbcmd &= USBCMD_ATDTW_TRIPWIRE_CLEAR; |
342 | writel(tmp, &udc->op_regs->usbcmd); | 337 | writel(usbcmd, &udc->op_regs->usbcmd); |
343 | |||
344 | /* If endpoint is not active, we activate it now. */ | ||
345 | if (!epstatus) { | ||
346 | if (direction == EP_DIR_IN) { | ||
347 | struct mv_dtd *curr_dtd = dma_to_virt( | ||
348 | &udc->dev->dev, dqh->curr_dtd_ptr); | ||
349 | |||
350 | loops = LOOPS(DTD_TIMEOUT); | ||
351 | while (curr_dtd->size_ioc_sts | ||
352 | & DTD_STATUS_ACTIVE) { | ||
353 | if (loops == 0) { | ||
354 | retval = -ETIME; | ||
355 | goto done; | ||
356 | } | ||
357 | loops--; | ||
358 | udelay(LOOPS_USEC); | ||
359 | } | ||
360 | } | ||
361 | /* No other transfers on the queue */ | ||
362 | 338 | ||
363 | /* Write dQH next pointer and terminate bit to 0 */ | 339 | if (epstatus) |
364 | dqh->next_dtd_ptr = req->head->td_dma | 340 | goto done; |
365 | & EP_QUEUE_HEAD_NEXT_POINTER_MASK; | 341 | } |
366 | dqh->size_ioc_int_sts = 0; | ||
367 | 342 | ||
368 | /* | 343 | /* Write dQH next pointer and terminate bit to 0 */ |
369 | * Ensure that updates to the QH will | 344 | dqh->next_dtd_ptr = req->head->td_dma |
370 | * occur before priming. | 345 | & EP_QUEUE_HEAD_NEXT_POINTER_MASK; |
371 | */ | ||
372 | wmb(); | ||
373 | 346 | ||
374 | /* Prime the Endpoint */ | 347 | /* clear active and halt bit, in case set from a previous error */ |
375 | writel(bit_pos, &udc->op_regs->epprime); | 348 | dqh->size_ioc_int_sts &= ~(DTD_STATUS_ACTIVE | DTD_STATUS_HALTED); |
376 | } | ||
377 | } else { | ||
378 | /* Write dQH next pointer and terminate bit to 0 */ | ||
379 | dqh->next_dtd_ptr = req->head->td_dma | ||
380 | & EP_QUEUE_HEAD_NEXT_POINTER_MASK; | ||
381 | dqh->size_ioc_int_sts = 0; | ||
382 | 349 | ||
383 | /* Ensure that updates to the QH will occur before priming. */ | 350 | /* Ensure that updates to the QH will occure before priming. */ |
384 | wmb(); | 351 | wmb(); |
385 | 352 | ||
386 | /* Prime the Endpoint */ | 353 | /* Prime the Endpoint */ |
387 | writel(bit_pos, &udc->op_regs->epprime); | 354 | writel(bit_pos, &udc->op_regs->epprime); |
388 | 355 | ||
389 | if (direction == EP_DIR_IN) { | ||
390 | /* FIXME add status check after prime the IN ep */ | ||
391 | int prime_again; | ||
392 | u32 curr_dtd_ptr = dqh->curr_dtd_ptr; | ||
393 | |||
394 | loops = LOOPS(DTD_TIMEOUT); | ||
395 | prime_again = 0; | ||
396 | while ((curr_dtd_ptr != req->head->td_dma)) { | ||
397 | curr_dtd_ptr = dqh->curr_dtd_ptr; | ||
398 | if (loops == 0) { | ||
399 | dev_err(&udc->dev->dev, | ||
400 | "failed to prime %s\n", | ||
401 | ep->name); | ||
402 | retval = -ETIME; | ||
403 | goto done; | ||
404 | } | ||
405 | loops--; | ||
406 | udelay(LOOPS_USEC); | ||
407 | |||
408 | if (loops == (LOOPS(DTD_TIMEOUT) >> 2)) { | ||
409 | if (prime_again) | ||
410 | goto done; | ||
411 | dev_info(&udc->dev->dev, | ||
412 | "prime again\n"); | ||
413 | writel(bit_pos, | ||
414 | &udc->op_regs->epprime); | ||
415 | prime_again = 1; | ||
416 | } | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | done: | 356 | done: |
421 | return retval; | 357 | return retval; |
422 | } | 358 | } |
423 | 359 | ||
360 | |||
424 | static struct mv_dtd *build_dtd(struct mv_req *req, unsigned *length, | 361 | static struct mv_dtd *build_dtd(struct mv_req *req, unsigned *length, |
425 | dma_addr_t *dma, int *is_last) | 362 | dma_addr_t *dma, int *is_last) |
426 | { | 363 | { |
@@ -841,6 +778,27 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
841 | return 0; | 778 | return 0; |
842 | } | 779 | } |
843 | 780 | ||
781 | static void mv_prime_ep(struct mv_ep *ep, struct mv_req *req) | ||
782 | { | ||
783 | struct mv_dqh *dqh = ep->dqh; | ||
784 | u32 bit_pos; | ||
785 | |||
786 | /* Write dQH next pointer and terminate bit to 0 */ | ||
787 | dqh->next_dtd_ptr = req->head->td_dma | ||
788 | & EP_QUEUE_HEAD_NEXT_POINTER_MASK; | ||
789 | |||
790 | /* clear active and halt bit, in case set from a previous error */ | ||
791 | dqh->size_ioc_int_sts &= ~(DTD_STATUS_ACTIVE | DTD_STATUS_HALTED); | ||
792 | |||
793 | /* Ensure that updates to the QH will occure before priming. */ | ||
794 | wmb(); | ||
795 | |||
796 | bit_pos = 1 << (((ep_dir(ep) == EP_DIR_OUT) ? 0 : 16) + ep->ep_num); | ||
797 | |||
798 | /* Prime the Endpoint */ | ||
799 | writel(bit_pos, &ep->udc->op_regs->epprime); | ||
800 | } | ||
801 | |||
844 | /* dequeues (cancels, unlinks) an I/O request from an endpoint */ | 802 | /* dequeues (cancels, unlinks) an I/O request from an endpoint */ |
845 | static int mv_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | 803 | static int mv_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) |
846 | { | 804 | { |
@@ -883,15 +841,13 @@ static int mv_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
883 | 841 | ||
884 | /* The request isn't the last request in this ep queue */ | 842 | /* The request isn't the last request in this ep queue */ |
885 | if (req->queue.next != &ep->queue) { | 843 | if (req->queue.next != &ep->queue) { |
886 | struct mv_dqh *qh; | ||
887 | struct mv_req *next_req; | 844 | struct mv_req *next_req; |
888 | 845 | ||
889 | qh = ep->dqh; | 846 | next_req = list_entry(req->queue.next, |
890 | next_req = list_entry(req->queue.next, struct mv_req, | 847 | struct mv_req, queue); |
891 | queue); | ||
892 | 848 | ||
893 | /* Point the QH to the first TD of next request */ | 849 | /* Point the QH to the first TD of next request */ |
894 | writel((u32) next_req->head, &qh->curr_dtd_ptr); | 850 | mv_prime_ep(ep, next_req); |
895 | } else { | 851 | } else { |
896 | struct mv_dqh *qh; | 852 | struct mv_dqh *qh; |
897 | 853 | ||
@@ -1056,6 +1012,8 @@ static void udc_stop(struct mv_udc *udc) | |||
1056 | USBINTR_PORT_CHANGE_DETECT_EN | USBINTR_RESET_EN); | 1012 | USBINTR_PORT_CHANGE_DETECT_EN | USBINTR_RESET_EN); |
1057 | writel(tmp, &udc->op_regs->usbintr); | 1013 | writel(tmp, &udc->op_regs->usbintr); |
1058 | 1014 | ||
1015 | udc->stopped = 1; | ||
1016 | |||
1059 | /* Reset the Run the bit in the command register to stop VUSB */ | 1017 | /* Reset the Run the bit in the command register to stop VUSB */ |
1060 | tmp = readl(&udc->op_regs->usbcmd); | 1018 | tmp = readl(&udc->op_regs->usbcmd); |
1061 | tmp &= ~USBCMD_RUN_STOP; | 1019 | tmp &= ~USBCMD_RUN_STOP; |
@@ -1072,6 +1030,8 @@ static void udc_start(struct mv_udc *udc) | |||
1072 | /* Enable interrupts */ | 1030 | /* Enable interrupts */ |
1073 | writel(usbintr, &udc->op_regs->usbintr); | 1031 | writel(usbintr, &udc->op_regs->usbintr); |
1074 | 1032 | ||
1033 | udc->stopped = 0; | ||
1034 | |||
1075 | /* Set the Run bit in the command register */ | 1035 | /* Set the Run bit in the command register */ |
1076 | writel(USBCMD_RUN_STOP, &udc->op_regs->usbcmd); | 1036 | writel(USBCMD_RUN_STOP, &udc->op_regs->usbcmd); |
1077 | } | 1037 | } |
@@ -1134,11 +1094,11 @@ static int udc_reset(struct mv_udc *udc) | |||
1134 | return 0; | 1094 | return 0; |
1135 | } | 1095 | } |
1136 | 1096 | ||
1137 | static int mv_udc_enable(struct mv_udc *udc) | 1097 | static int mv_udc_enable_internal(struct mv_udc *udc) |
1138 | { | 1098 | { |
1139 | int retval; | 1099 | int retval; |
1140 | 1100 | ||
1141 | if (udc->clock_gating == 0 || udc->active) | 1101 | if (udc->active) |
1142 | return 0; | 1102 | return 0; |
1143 | 1103 | ||
1144 | dev_dbg(&udc->dev->dev, "enable udc\n"); | 1104 | dev_dbg(&udc->dev->dev, "enable udc\n"); |
@@ -1157,9 +1117,17 @@ static int mv_udc_enable(struct mv_udc *udc) | |||
1157 | return 0; | 1117 | return 0; |
1158 | } | 1118 | } |
1159 | 1119 | ||
1160 | static void mv_udc_disable(struct mv_udc *udc) | 1120 | static int mv_udc_enable(struct mv_udc *udc) |
1161 | { | 1121 | { |
1162 | if (udc->clock_gating && udc->active) { | 1122 | if (udc->clock_gating) |
1123 | return mv_udc_enable_internal(udc); | ||
1124 | |||
1125 | return 0; | ||
1126 | } | ||
1127 | |||
1128 | static void mv_udc_disable_internal(struct mv_udc *udc) | ||
1129 | { | ||
1130 | if (udc->active) { | ||
1163 | dev_dbg(&udc->dev->dev, "disable udc\n"); | 1131 | dev_dbg(&udc->dev->dev, "disable udc\n"); |
1164 | if (udc->pdata->phy_deinit) | 1132 | if (udc->pdata->phy_deinit) |
1165 | udc->pdata->phy_deinit(udc->phy_regs); | 1133 | udc->pdata->phy_deinit(udc->phy_regs); |
@@ -1168,6 +1136,12 @@ static void mv_udc_disable(struct mv_udc *udc) | |||
1168 | } | 1136 | } |
1169 | } | 1137 | } |
1170 | 1138 | ||
1139 | static void mv_udc_disable(struct mv_udc *udc) | ||
1140 | { | ||
1141 | if (udc->clock_gating) | ||
1142 | mv_udc_disable_internal(udc); | ||
1143 | } | ||
1144 | |||
1171 | static int mv_udc_get_frame(struct usb_gadget *gadget) | 1145 | static int mv_udc_get_frame(struct usb_gadget *gadget) |
1172 | { | 1146 | { |
1173 | struct mv_udc *udc; | 1147 | struct mv_udc *udc; |
@@ -1178,7 +1152,7 @@ static int mv_udc_get_frame(struct usb_gadget *gadget) | |||
1178 | 1152 | ||
1179 | udc = container_of(gadget, struct mv_udc, gadget); | 1153 | udc = container_of(gadget, struct mv_udc, gadget); |
1180 | 1154 | ||
1181 | retval = readl(udc->op_regs->frindex) & USB_FRINDEX_MASKS; | 1155 | retval = readl(&udc->op_regs->frindex) & USB_FRINDEX_MASKS; |
1182 | 1156 | ||
1183 | return retval; | 1157 | return retval; |
1184 | } | 1158 | } |
@@ -1212,10 +1186,11 @@ static int mv_udc_vbus_session(struct usb_gadget *gadget, int is_active) | |||
1212 | udc = container_of(gadget, struct mv_udc, gadget); | 1186 | udc = container_of(gadget, struct mv_udc, gadget); |
1213 | spin_lock_irqsave(&udc->lock, flags); | 1187 | spin_lock_irqsave(&udc->lock, flags); |
1214 | 1188 | ||
1189 | udc->vbus_active = (is_active != 0); | ||
1190 | |||
1215 | dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n", | 1191 | dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n", |
1216 | __func__, udc->softconnect, udc->vbus_active); | 1192 | __func__, udc->softconnect, udc->vbus_active); |
1217 | 1193 | ||
1218 | udc->vbus_active = (is_active != 0); | ||
1219 | if (udc->driver && udc->softconnect && udc->vbus_active) { | 1194 | if (udc->driver && udc->softconnect && udc->vbus_active) { |
1220 | retval = mv_udc_enable(udc); | 1195 | retval = mv_udc_enable(udc); |
1221 | if (retval == 0) { | 1196 | if (retval == 0) { |
@@ -1244,10 +1219,11 @@ static int mv_udc_pullup(struct usb_gadget *gadget, int is_on) | |||
1244 | udc = container_of(gadget, struct mv_udc, gadget); | 1219 | udc = container_of(gadget, struct mv_udc, gadget); |
1245 | spin_lock_irqsave(&udc->lock, flags); | 1220 | spin_lock_irqsave(&udc->lock, flags); |
1246 | 1221 | ||
1222 | udc->softconnect = (is_on != 0); | ||
1223 | |||
1247 | dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n", | 1224 | dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n", |
1248 | __func__, udc->softconnect, udc->vbus_active); | 1225 | __func__, udc->softconnect, udc->vbus_active); |
1249 | 1226 | ||
1250 | udc->softconnect = (is_on != 0); | ||
1251 | if (udc->driver && udc->softconnect && udc->vbus_active) { | 1227 | if (udc->driver && udc->softconnect && udc->vbus_active) { |
1252 | retval = mv_udc_enable(udc); | 1228 | retval = mv_udc_enable(udc); |
1253 | if (retval == 0) { | 1229 | if (retval == 0) { |
@@ -1407,6 +1383,20 @@ static int mv_udc_start(struct usb_gadget_driver *driver, | |||
1407 | return retval; | 1383 | return retval; |
1408 | } | 1384 | } |
1409 | 1385 | ||
1386 | if (udc->transceiver) { | ||
1387 | retval = otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
1388 | if (retval) { | ||
1389 | dev_err(&udc->dev->dev, | ||
1390 | "unable to register peripheral to otg\n"); | ||
1391 | if (driver->unbind) { | ||
1392 | driver->unbind(&udc->gadget); | ||
1393 | udc->gadget.dev.driver = NULL; | ||
1394 | udc->driver = NULL; | ||
1395 | } | ||
1396 | return retval; | ||
1397 | } | ||
1398 | } | ||
1399 | |||
1410 | /* pullup is always on */ | 1400 | /* pullup is always on */ |
1411 | mv_udc_pullup(&udc->gadget, 1); | 1401 | mv_udc_pullup(&udc->gadget, 1); |
1412 | 1402 | ||
@@ -2026,6 +2016,10 @@ static irqreturn_t mv_udc_irq(int irq, void *dev) | |||
2026 | struct mv_udc *udc = (struct mv_udc *)dev; | 2016 | struct mv_udc *udc = (struct mv_udc *)dev; |
2027 | u32 status, intr; | 2017 | u32 status, intr; |
2028 | 2018 | ||
2019 | /* Disable ISR when stopped bit is set */ | ||
2020 | if (udc->stopped) | ||
2021 | return IRQ_NONE; | ||
2022 | |||
2029 | spin_lock(&udc->lock); | 2023 | spin_lock(&udc->lock); |
2030 | 2024 | ||
2031 | status = readl(&udc->op_regs->usbsts); | 2025 | status = readl(&udc->op_regs->usbsts); |
@@ -2109,7 +2103,12 @@ static int __devexit mv_udc_remove(struct platform_device *dev) | |||
2109 | destroy_workqueue(udc->qwork); | 2103 | destroy_workqueue(udc->qwork); |
2110 | } | 2104 | } |
2111 | 2105 | ||
2112 | if (udc->pdata && udc->pdata->vbus && udc->clock_gating) | 2106 | /* |
2107 | * If we have transceiver inited, | ||
2108 | * then vbus irq will not be requested in udc driver. | ||
2109 | */ | ||
2110 | if (udc->pdata && udc->pdata->vbus | ||
2111 | && udc->clock_gating && udc->transceiver == NULL) | ||
2113 | free_irq(udc->pdata->vbus->irq, &dev->dev); | 2112 | free_irq(udc->pdata->vbus->irq, &dev->dev); |
2114 | 2113 | ||
2115 | /* free memory allocated in probe */ | 2114 | /* free memory allocated in probe */ |
@@ -2129,11 +2128,9 @@ static int __devexit mv_udc_remove(struct platform_device *dev) | |||
2129 | 2128 | ||
2130 | if (udc->cap_regs) | 2129 | if (udc->cap_regs) |
2131 | iounmap(udc->cap_regs); | 2130 | iounmap(udc->cap_regs); |
2132 | udc->cap_regs = NULL; | ||
2133 | 2131 | ||
2134 | if (udc->phy_regs) | 2132 | if (udc->phy_regs) |
2135 | iounmap((void *)udc->phy_regs); | 2133 | iounmap(udc->phy_regs); |
2136 | udc->phy_regs = 0; | ||
2137 | 2134 | ||
2138 | if (udc->status_req) { | 2135 | if (udc->status_req) { |
2139 | kfree(udc->status_req->req.buf); | 2136 | kfree(udc->status_req->req.buf); |
@@ -2182,6 +2179,11 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2182 | 2179 | ||
2183 | udc->dev = dev; | 2180 | udc->dev = dev; |
2184 | 2181 | ||
2182 | #ifdef CONFIG_USB_OTG_UTILS | ||
2183 | if (pdata->mode == MV_USB_MODE_OTG) | ||
2184 | udc->transceiver = otg_get_transceiver(); | ||
2185 | #endif | ||
2186 | |||
2185 | udc->clknum = pdata->clknum; | 2187 | udc->clknum = pdata->clknum; |
2186 | for (clk_i = 0; clk_i < udc->clknum; clk_i++) { | 2188 | for (clk_i = 0; clk_i < udc->clknum; clk_i++) { |
2187 | udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[clk_i]); | 2189 | udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[clk_i]); |
@@ -2213,24 +2215,20 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2213 | goto err_iounmap_capreg; | 2215 | goto err_iounmap_capreg; |
2214 | } | 2216 | } |
2215 | 2217 | ||
2216 | udc->phy_regs = (unsigned int)ioremap(r->start, resource_size(r)); | 2218 | udc->phy_regs = ioremap(r->start, resource_size(r)); |
2217 | if (udc->phy_regs == 0) { | 2219 | if (udc->phy_regs == NULL) { |
2218 | dev_err(&dev->dev, "failed to map phy I/O memory\n"); | 2220 | dev_err(&dev->dev, "failed to map phy I/O memory\n"); |
2219 | retval = -EBUSY; | 2221 | retval = -EBUSY; |
2220 | goto err_iounmap_capreg; | 2222 | goto err_iounmap_capreg; |
2221 | } | 2223 | } |
2222 | 2224 | ||
2223 | /* we will acces controller register, so enable the clk */ | 2225 | /* we will acces controller register, so enable the clk */ |
2224 | udc_clock_enable(udc); | 2226 | retval = mv_udc_enable_internal(udc); |
2225 | if (pdata->phy_init) { | 2227 | if (retval) |
2226 | retval = pdata->phy_init(udc->phy_regs); | 2228 | goto err_iounmap_phyreg; |
2227 | if (retval) { | ||
2228 | dev_err(&dev->dev, "phy init error %d\n", retval); | ||
2229 | goto err_iounmap_phyreg; | ||
2230 | } | ||
2231 | } | ||
2232 | 2229 | ||
2233 | udc->op_regs = (struct mv_op_regs __iomem *)((u32)udc->cap_regs | 2230 | udc->op_regs = |
2231 | (struct mv_op_regs __iomem *)((unsigned long)udc->cap_regs | ||
2234 | + (readl(&udc->cap_regs->caplength_hciversion) | 2232 | + (readl(&udc->cap_regs->caplength_hciversion) |
2235 | & CAPLENGTH_MASK)); | 2233 | & CAPLENGTH_MASK)); |
2236 | udc->max_eps = readl(&udc->cap_regs->dccparams) & DCCPARAMS_DEN_MASK; | 2234 | udc->max_eps = readl(&udc->cap_regs->dccparams) & DCCPARAMS_DEN_MASK; |
@@ -2312,7 +2310,7 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2312 | udc->gadget.ep0 = &udc->eps[0].ep; /* gadget ep0 */ | 2310 | udc->gadget.ep0 = &udc->eps[0].ep; /* gadget ep0 */ |
2313 | INIT_LIST_HEAD(&udc->gadget.ep_list); /* ep_list */ | 2311 | INIT_LIST_HEAD(&udc->gadget.ep_list); /* ep_list */ |
2314 | udc->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ | 2312 | udc->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ |
2315 | udc->gadget.is_dualspeed = 1; /* support dual speed */ | 2313 | udc->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */ |
2316 | 2314 | ||
2317 | /* the "gadget" abstracts/virtualizes the controller */ | 2315 | /* the "gadget" abstracts/virtualizes the controller */ |
2318 | dev_set_name(&udc->gadget.dev, "gadget"); | 2316 | dev_set_name(&udc->gadget.dev, "gadget"); |
@@ -2328,7 +2326,9 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2328 | eps_init(udc); | 2326 | eps_init(udc); |
2329 | 2327 | ||
2330 | /* VBUS detect: we can disable/enable clock on demand.*/ | 2328 | /* VBUS detect: we can disable/enable clock on demand.*/ |
2331 | if (pdata->vbus) { | 2329 | if (udc->transceiver) |
2330 | udc->clock_gating = 1; | ||
2331 | else if (pdata->vbus) { | ||
2332 | udc->clock_gating = 1; | 2332 | udc->clock_gating = 1; |
2333 | retval = request_threaded_irq(pdata->vbus->irq, NULL, | 2333 | retval = request_threaded_irq(pdata->vbus->irq, NULL, |
2334 | mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc); | 2334 | mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc); |
@@ -2354,11 +2354,9 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2354 | * If not, it means that VBUS detection is not supported, we | 2354 | * If not, it means that VBUS detection is not supported, we |
2355 | * have to enable vbus active all the time to let controller work. | 2355 | * have to enable vbus active all the time to let controller work. |
2356 | */ | 2356 | */ |
2357 | if (udc->clock_gating) { | 2357 | if (udc->clock_gating) |
2358 | if (udc->pdata->phy_deinit) | 2358 | mv_udc_disable_internal(udc); |
2359 | udc->pdata->phy_deinit(udc->phy_regs); | 2359 | else |
2360 | udc_clock_disable(udc); | ||
2361 | } else | ||
2362 | udc->vbus_active = 1; | 2360 | udc->vbus_active = 1; |
2363 | 2361 | ||
2364 | retval = usb_add_gadget_udc(&dev->dev, &udc->gadget); | 2362 | retval = usb_add_gadget_udc(&dev->dev, &udc->gadget); |
@@ -2371,7 +2369,8 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2371 | return 0; | 2369 | return 0; |
2372 | 2370 | ||
2373 | err_unregister: | 2371 | err_unregister: |
2374 | if (udc->pdata && udc->pdata->vbus && udc->clock_gating) | 2372 | if (udc->pdata && udc->pdata->vbus |
2373 | && udc->clock_gating && udc->transceiver == NULL) | ||
2375 | free_irq(pdata->vbus->irq, &dev->dev); | 2374 | free_irq(pdata->vbus->irq, &dev->dev); |
2376 | device_unregister(&udc->gadget.dev); | 2375 | device_unregister(&udc->gadget.dev); |
2377 | err_free_irq: | 2376 | err_free_irq: |
@@ -2387,11 +2386,9 @@ err_free_dma: | |||
2387 | dma_free_coherent(&dev->dev, udc->ep_dqh_size, | 2386 | dma_free_coherent(&dev->dev, udc->ep_dqh_size, |
2388 | udc->ep_dqh, udc->ep_dqh_dma); | 2387 | udc->ep_dqh, udc->ep_dqh_dma); |
2389 | err_disable_clock: | 2388 | err_disable_clock: |
2390 | if (udc->pdata->phy_deinit) | 2389 | mv_udc_disable_internal(udc); |
2391 | udc->pdata->phy_deinit(udc->phy_regs); | ||
2392 | udc_clock_disable(udc); | ||
2393 | err_iounmap_phyreg: | 2390 | err_iounmap_phyreg: |
2394 | iounmap((void *)udc->phy_regs); | 2391 | iounmap(udc->phy_regs); |
2395 | err_iounmap_capreg: | 2392 | err_iounmap_capreg: |
2396 | iounmap(udc->cap_regs); | 2393 | iounmap(udc->cap_regs); |
2397 | err_put_clk: | 2394 | err_put_clk: |
@@ -2407,7 +2404,30 @@ static int mv_udc_suspend(struct device *_dev) | |||
2407 | { | 2404 | { |
2408 | struct mv_udc *udc = the_controller; | 2405 | struct mv_udc *udc = the_controller; |
2409 | 2406 | ||
2410 | udc_stop(udc); | 2407 | /* if OTG is enabled, the following will be done in OTG driver*/ |
2408 | if (udc->transceiver) | ||
2409 | return 0; | ||
2410 | |||
2411 | if (udc->pdata->vbus && udc->pdata->vbus->poll) | ||
2412 | if (udc->pdata->vbus->poll() == VBUS_HIGH) { | ||
2413 | dev_info(&udc->dev->dev, "USB cable is connected!\n"); | ||
2414 | return -EAGAIN; | ||
2415 | } | ||
2416 | |||
2417 | /* | ||
2418 | * only cable is unplugged, udc can suspend. | ||
2419 | * So do not care about clock_gating == 1. | ||
2420 | */ | ||
2421 | if (!udc->clock_gating) { | ||
2422 | udc_stop(udc); | ||
2423 | |||
2424 | spin_lock_irq(&udc->lock); | ||
2425 | /* stop all usb activities */ | ||
2426 | stop_activity(udc, udc->driver); | ||
2427 | spin_unlock_irq(&udc->lock); | ||
2428 | |||
2429 | mv_udc_disable_internal(udc); | ||
2430 | } | ||
2411 | 2431 | ||
2412 | return 0; | 2432 | return 0; |
2413 | } | 2433 | } |
@@ -2417,20 +2437,22 @@ static int mv_udc_resume(struct device *_dev) | |||
2417 | struct mv_udc *udc = the_controller; | 2437 | struct mv_udc *udc = the_controller; |
2418 | int retval; | 2438 | int retval; |
2419 | 2439 | ||
2420 | if (udc->pdata->phy_init) { | 2440 | /* if OTG is enabled, the following will be done in OTG driver*/ |
2421 | retval = udc->pdata->phy_init(udc->phy_regs); | 2441 | if (udc->transceiver) |
2422 | if (retval) { | 2442 | return 0; |
2423 | dev_err(&udc->dev->dev, | 2443 | |
2424 | "init phy error %d when resume back\n", | 2444 | if (!udc->clock_gating) { |
2425 | retval); | 2445 | retval = mv_udc_enable_internal(udc); |
2446 | if (retval) | ||
2426 | return retval; | 2447 | return retval; |
2448 | |||
2449 | if (udc->driver && udc->softconnect) { | ||
2450 | udc_reset(udc); | ||
2451 | ep0_reset(udc); | ||
2452 | udc_start(udc); | ||
2427 | } | 2453 | } |
2428 | } | 2454 | } |
2429 | 2455 | ||
2430 | udc_reset(udc); | ||
2431 | ep0_reset(udc); | ||
2432 | udc_start(udc); | ||
2433 | |||
2434 | return 0; | 2456 | return 0; |
2435 | } | 2457 | } |
2436 | 2458 | ||
@@ -2457,30 +2479,16 @@ static struct platform_driver udc_driver = { | |||
2457 | .shutdown = mv_udc_shutdown, | 2479 | .shutdown = mv_udc_shutdown, |
2458 | .driver = { | 2480 | .driver = { |
2459 | .owner = THIS_MODULE, | 2481 | .owner = THIS_MODULE, |
2460 | .name = "pxa-u2o", | 2482 | .name = "mv-udc", |
2461 | #ifdef CONFIG_PM | 2483 | #ifdef CONFIG_PM |
2462 | .pm = &mv_udc_pm_ops, | 2484 | .pm = &mv_udc_pm_ops, |
2463 | #endif | 2485 | #endif |
2464 | }, | 2486 | }, |
2465 | }; | 2487 | }; |
2466 | MODULE_ALIAS("platform:pxa-u2o"); | ||
2467 | 2488 | ||
2489 | module_platform_driver(udc_driver); | ||
2490 | MODULE_ALIAS("platform:mv-udc"); | ||
2468 | MODULE_DESCRIPTION(DRIVER_DESC); | 2491 | MODULE_DESCRIPTION(DRIVER_DESC); |
2469 | MODULE_AUTHOR("Chao Xie <chao.xie@marvell.com>"); | 2492 | MODULE_AUTHOR("Chao Xie <chao.xie@marvell.com>"); |
2470 | MODULE_VERSION(DRIVER_VERSION); | 2493 | MODULE_VERSION(DRIVER_VERSION); |
2471 | MODULE_LICENSE("GPL"); | 2494 | MODULE_LICENSE("GPL"); |
2472 | |||
2473 | |||
2474 | static int __init init(void) | ||
2475 | { | ||
2476 | return platform_driver_register(&udc_driver); | ||
2477 | } | ||
2478 | module_init(init); | ||
2479 | |||
2480 | |||
2481 | static void __exit cleanup(void) | ||
2482 | { | ||
2483 | platform_driver_unregister(&udc_driver); | ||
2484 | } | ||
2485 | module_exit(cleanup); | ||
2486 | |||
diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index d1b76368472f..4c81d540bc26 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c | |||
@@ -1459,7 +1459,7 @@ static int net2272_start(struct usb_gadget *_gadget, | |||
1459 | unsigned i; | 1459 | unsigned i; |
1460 | 1460 | ||
1461 | if (!driver || !driver->unbind || !driver->setup || | 1461 | if (!driver || !driver->unbind || !driver->setup || |
1462 | driver->speed != USB_SPEED_HIGH) | 1462 | driver->max_speed != USB_SPEED_HIGH) |
1463 | return -EINVAL; | 1463 | return -EINVAL; |
1464 | 1464 | ||
1465 | dev = container_of(_gadget, struct net2272, gadget); | 1465 | dev = container_of(_gadget, struct net2272, gadget); |
@@ -2235,7 +2235,7 @@ net2272_probe_init(struct device *dev, unsigned int irq) | |||
2235 | ret->irq = irq; | 2235 | ret->irq = irq; |
2236 | ret->dev = dev; | 2236 | ret->dev = dev; |
2237 | ret->gadget.ops = &net2272_ops; | 2237 | ret->gadget.ops = &net2272_ops; |
2238 | ret->gadget.is_dualspeed = 1; | 2238 | ret->gadget.max_speed = USB_SPEED_HIGH; |
2239 | 2239 | ||
2240 | /* the "gadget" abstracts/virtualizes the controller */ | 2240 | /* the "gadget" abstracts/virtualizes the controller */ |
2241 | dev_set_name(&ret->gadget.dev, "gadget"); | 2241 | dev_set_name(&ret->gadget.dev, "gadget"); |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index da2b9d0be3ca..cf1f36454d08 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -1881,7 +1881,7 @@ static int net2280_start(struct usb_gadget *_gadget, | |||
1881 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) | 1881 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) |
1882 | * "must not be used in normal operation" | 1882 | * "must not be used in normal operation" |
1883 | */ | 1883 | */ |
1884 | if (!driver || driver->speed < USB_SPEED_HIGH | 1884 | if (!driver || driver->max_speed < USB_SPEED_HIGH |
1885 | || !driver->setup) | 1885 | || !driver->setup) |
1886 | return -EINVAL; | 1886 | return -EINVAL; |
1887 | 1887 | ||
@@ -2698,7 +2698,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
2698 | spin_lock_init (&dev->lock); | 2698 | spin_lock_init (&dev->lock); |
2699 | dev->pdev = pdev; | 2699 | dev->pdev = pdev; |
2700 | dev->gadget.ops = &net2280_ops; | 2700 | dev->gadget.ops = &net2280_ops; |
2701 | dev->gadget.is_dualspeed = 1; | 2701 | dev->gadget.max_speed = USB_SPEED_HIGH; |
2702 | 2702 | ||
2703 | /* the "gadget" abstracts/virtualizes the controller */ | 2703 | /* the "gadget" abstracts/virtualizes the controller */ |
2704 | dev_set_name(&dev->gadget.dev, "gadget"); | 2704 | dev_set_name(&dev->gadget.dev, "gadget"); |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 788989a10223..7db5bbe6251b 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -2110,7 +2110,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver, | |||
2110 | return -ENODEV; | 2110 | return -ENODEV; |
2111 | if (!driver | 2111 | if (!driver |
2112 | // FIXME if otg, check: driver->is_otg | 2112 | // FIXME if otg, check: driver->is_otg |
2113 | || driver->speed < USB_SPEED_FULL | 2113 | || driver->max_speed < USB_SPEED_FULL |
2114 | || !bind || !driver->setup) | 2114 | || !bind || !driver->setup) |
2115 | return -EINVAL; | 2115 | return -EINVAL; |
2116 | 2116 | ||
@@ -2676,6 +2676,7 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) | |||
2676 | INIT_LIST_HEAD(&udc->gadget.ep_list); | 2676 | INIT_LIST_HEAD(&udc->gadget.ep_list); |
2677 | INIT_LIST_HEAD(&udc->iso); | 2677 | INIT_LIST_HEAD(&udc->iso); |
2678 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 2678 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
2679 | udc->gadget.max_speed = USB_SPEED_FULL; | ||
2679 | udc->gadget.name = driver_name; | 2680 | udc->gadget.name = driver_name; |
2680 | 2681 | ||
2681 | device_initialize(&udc->gadget.dev); | 2682 | device_initialize(&udc->gadget.dev); |
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 5048a0c07640..dd2313cce1d3 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c | |||
@@ -2693,7 +2693,7 @@ static int pch_udc_start(struct usb_gadget_driver *driver, | |||
2693 | struct pch_udc_dev *dev = pch_udc; | 2693 | struct pch_udc_dev *dev = pch_udc; |
2694 | int retval; | 2694 | int retval; |
2695 | 2695 | ||
2696 | if (!driver || (driver->speed == USB_SPEED_UNKNOWN) || !bind || | 2696 | if (!driver || (driver->max_speed == USB_SPEED_UNKNOWN) || !bind || |
2697 | !driver->setup || !driver->unbind || !driver->disconnect) { | 2697 | !driver->setup || !driver->unbind || !driver->disconnect) { |
2698 | dev_err(&dev->pdev->dev, | 2698 | dev_err(&dev->pdev->dev, |
2699 | "%s: invalid driver parameter\n", __func__); | 2699 | "%s: invalid driver parameter\n", __func__); |
@@ -2941,7 +2941,7 @@ static int pch_udc_probe(struct pci_dev *pdev, | |||
2941 | dev->gadget.dev.dma_mask = pdev->dev.dma_mask; | 2941 | dev->gadget.dev.dma_mask = pdev->dev.dma_mask; |
2942 | dev->gadget.dev.release = gadget_release; | 2942 | dev->gadget.dev.release = gadget_release; |
2943 | dev->gadget.name = KBUILD_MODNAME; | 2943 | dev->gadget.name = KBUILD_MODNAME; |
2944 | dev->gadget.is_dualspeed = 1; | 2944 | dev->gadget.max_speed = USB_SPEED_HIGH; |
2945 | 2945 | ||
2946 | retval = device_register(&dev->gadget.dev); | 2946 | retval = device_register(&dev->gadget.dev); |
2947 | if (retval) | 2947 | if (retval) |
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 65a8834f274b..d83134b0f78a 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -1141,7 +1141,7 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1141 | break; | 1141 | break; |
1142 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1142 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1143 | case USB_DT_DEVICE_QUALIFIER: | 1143 | case USB_DT_DEVICE_QUALIFIER: |
1144 | if (!gadget->is_dualspeed) | 1144 | if (!gadget_is_dualspeed(gadget)) |
1145 | break; | 1145 | break; |
1146 | /* | 1146 | /* |
1147 | * assumes ep0 uses the same value for both | 1147 | * assumes ep0 uses the same value for both |
@@ -1155,7 +1155,7 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1155 | break; | 1155 | break; |
1156 | 1156 | ||
1157 | case USB_DT_OTHER_SPEED_CONFIG: | 1157 | case USB_DT_OTHER_SPEED_CONFIG: |
1158 | if (!gadget->is_dualspeed) | 1158 | if (!gadget_is_dualspeed(gadget)) |
1159 | break; | 1159 | break; |
1160 | /* FALLTHROUGH */ | 1160 | /* FALLTHROUGH */ |
1161 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 1161 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ |
@@ -1535,7 +1535,7 @@ fail: | |||
1535 | /*-------------------------------------------------------------------------*/ | 1535 | /*-------------------------------------------------------------------------*/ |
1536 | 1536 | ||
1537 | static struct usb_gadget_driver printer_driver = { | 1537 | static struct usb_gadget_driver printer_driver = { |
1538 | .speed = DEVSPEED, | 1538 | .max_speed = DEVSPEED, |
1539 | 1539 | ||
1540 | .function = (char *) driver_desc, | 1540 | .function = (char *) driver_desc, |
1541 | .unbind = printer_unbind, | 1541 | .unbind = printer_unbind, |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index c090a7e3ecf8..dd470635f4f7 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -1264,7 +1264,7 @@ static int pxa25x_start(struct usb_gadget_driver *driver, | |||
1264 | int retval; | 1264 | int retval; |
1265 | 1265 | ||
1266 | if (!driver | 1266 | if (!driver |
1267 | || driver->speed < USB_SPEED_FULL | 1267 | || driver->max_speed < USB_SPEED_FULL |
1268 | || !bind | 1268 | || !bind |
1269 | || !driver->disconnect | 1269 | || !driver->disconnect |
1270 | || !driver->setup) | 1270 | || !driver->setup) |
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 18b6b091f2a6..f4c44eb806c3 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c | |||
@@ -1807,7 +1807,7 @@ static int pxa27x_udc_start(struct usb_gadget_driver *driver, | |||
1807 | struct pxa_udc *udc = the_controller; | 1807 | struct pxa_udc *udc = the_controller; |
1808 | int retval; | 1808 | int retval; |
1809 | 1809 | ||
1810 | if (!driver || driver->speed < USB_SPEED_FULL || !bind | 1810 | if (!driver || driver->max_speed < USB_SPEED_FULL || !bind |
1811 | || !driver->disconnect || !driver->setup) | 1811 | || !driver->disconnect || !driver->setup) |
1812 | return -EINVAL; | 1812 | return -EINVAL; |
1813 | if (!udc) | 1813 | if (!udc) |
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index fc719a3f8557..f5b8d215e1d5 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -1746,7 +1746,7 @@ static int r8a66597_start(struct usb_gadget *gadget, | |||
1746 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); | 1746 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); |
1747 | 1747 | ||
1748 | if (!driver | 1748 | if (!driver |
1749 | || driver->speed < USB_SPEED_HIGH | 1749 | || driver->max_speed < USB_SPEED_HIGH |
1750 | || !driver->setup) | 1750 | || !driver->setup) |
1751 | return -EINVAL; | 1751 | return -EINVAL; |
1752 | if (!r8a66597) | 1752 | if (!r8a66597) |
@@ -1911,7 +1911,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
1911 | 1911 | ||
1912 | r8a66597->gadget.ops = &r8a66597_gadget_ops; | 1912 | r8a66597->gadget.ops = &r8a66597_gadget_ops; |
1913 | dev_set_name(&r8a66597->gadget.dev, "gadget"); | 1913 | dev_set_name(&r8a66597->gadget.dev, "gadget"); |
1914 | r8a66597->gadget.is_dualspeed = 1; | 1914 | r8a66597->gadget.max_speed = USB_SPEED_HIGH; |
1915 | r8a66597->gadget.dev.parent = &pdev->dev; | 1915 | r8a66597->gadget.dev.parent = &pdev->dev; |
1916 | r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask; | 1916 | r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask; |
1917 | r8a66597->gadget.dev.release = pdev->dev.release; | 1917 | r8a66597->gadget.dev.release = pdev->dev.release; |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index b31448229f0b..69295ba9d99a 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -2586,7 +2586,7 @@ static int s3c_hsotg_start(struct usb_gadget_driver *driver, | |||
2586 | return -EINVAL; | 2586 | return -EINVAL; |
2587 | } | 2587 | } |
2588 | 2588 | ||
2589 | if (driver->speed < USB_SPEED_FULL) | 2589 | if (driver->max_speed < USB_SPEED_FULL) |
2590 | dev_err(hsotg->dev, "%s: bad speed\n", __func__); | 2590 | dev_err(hsotg->dev, "%s: bad speed\n", __func__); |
2591 | 2591 | ||
2592 | if (!bind || !driver->setup) { | 2592 | if (!bind || !driver->setup) { |
@@ -3362,7 +3362,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3362 | 3362 | ||
3363 | dev_set_name(&hsotg->gadget.dev, "gadget"); | 3363 | dev_set_name(&hsotg->gadget.dev, "gadget"); |
3364 | 3364 | ||
3365 | hsotg->gadget.is_dualspeed = 1; | 3365 | hsotg->gadget.max_speed = USB_SPEED_HIGH; |
3366 | hsotg->gadget.ops = &s3c_hsotg_gadget_ops; | 3366 | hsotg->gadget.ops = &s3c_hsotg_gadget_ops; |
3367 | hsotg->gadget.name = dev_name(dev); | 3367 | hsotg->gadget.name = dev_name(dev); |
3368 | 3368 | ||
@@ -3467,18 +3467,7 @@ static struct platform_driver s3c_hsotg_driver = { | |||
3467 | .resume = s3c_hsotg_resume, | 3467 | .resume = s3c_hsotg_resume, |
3468 | }; | 3468 | }; |
3469 | 3469 | ||
3470 | static int __init s3c_hsotg_modinit(void) | 3470 | module_platform_driver(s3c_hsotg_driver); |
3471 | { | ||
3472 | return platform_driver_register(&s3c_hsotg_driver); | ||
3473 | } | ||
3474 | |||
3475 | static void __exit s3c_hsotg_modexit(void) | ||
3476 | { | ||
3477 | platform_driver_unregister(&s3c_hsotg_driver); | ||
3478 | } | ||
3479 | |||
3480 | module_init(s3c_hsotg_modinit); | ||
3481 | module_exit(s3c_hsotg_modexit); | ||
3482 | 3471 | ||
3483 | MODULE_DESCRIPTION("Samsung S3C USB High-speed/OtG device"); | 3472 | MODULE_DESCRIPTION("Samsung S3C USB High-speed/OtG device"); |
3484 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | 3473 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); |
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 20a553b46aed..df8661d266cb 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c | |||
@@ -28,9 +28,10 @@ | |||
28 | #include <linux/usb/gadget.h> | 28 | #include <linux/usb/gadget.h> |
29 | #include <linux/usb/otg.h> | 29 | #include <linux/usb/otg.h> |
30 | #include <linux/prefetch.h> | 30 | #include <linux/prefetch.h> |
31 | #include <linux/platform_data/s3c-hsudc.h> | ||
32 | #include <linux/regulator/consumer.h> | ||
31 | 33 | ||
32 | #include <mach/regs-s3c2443-clock.h> | 34 | #include <mach/regs-s3c2443-clock.h> |
33 | #include <plat/udc.h> | ||
34 | 35 | ||
35 | #define S3C_HSUDC_REG(x) (x) | 36 | #define S3C_HSUDC_REG(x) (x) |
36 | 37 | ||
@@ -87,6 +88,12 @@ | |||
87 | #define DATA_STATE_XMIT (1) | 88 | #define DATA_STATE_XMIT (1) |
88 | #define DATA_STATE_RECV (2) | 89 | #define DATA_STATE_RECV (2) |
89 | 90 | ||
91 | static const char * const s3c_hsudc_supply_names[] = { | ||
92 | "vdda", /* analog phy supply, 3.3V */ | ||
93 | "vddi", /* digital phy supply, 1.2V */ | ||
94 | "vddosc", /* oscillator supply, 1.8V - 3.3V */ | ||
95 | }; | ||
96 | |||
90 | /** | 97 | /** |
91 | * struct s3c_hsudc_ep - Endpoint representation used by driver. | 98 | * struct s3c_hsudc_ep - Endpoint representation used by driver. |
92 | * @ep: USB gadget layer representation of device endpoint. | 99 | * @ep: USB gadget layer representation of device endpoint. |
@@ -139,6 +146,7 @@ struct s3c_hsudc { | |||
139 | struct device *dev; | 146 | struct device *dev; |
140 | struct s3c24xx_hsudc_platdata *pd; | 147 | struct s3c24xx_hsudc_platdata *pd; |
141 | struct otg_transceiver *transceiver; | 148 | struct otg_transceiver *transceiver; |
149 | struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsudc_supply_names)]; | ||
142 | spinlock_t lock; | 150 | spinlock_t lock; |
143 | void __iomem *regs; | 151 | void __iomem *regs; |
144 | struct resource *mem_rsrc; | 152 | struct resource *mem_rsrc; |
@@ -153,7 +161,6 @@ struct s3c_hsudc { | |||
153 | #define ep_index(_ep) ((_ep)->bEndpointAddress & \ | 161 | #define ep_index(_ep) ((_ep)->bEndpointAddress & \ |
154 | USB_ENDPOINT_NUMBER_MASK) | 162 | USB_ENDPOINT_NUMBER_MASK) |
155 | 163 | ||
156 | static struct s3c_hsudc *the_controller; | ||
157 | static const char driver_name[] = "s3c-udc"; | 164 | static const char driver_name[] = "s3c-udc"; |
158 | static const char ep0name[] = "ep0-control"; | 165 | static const char ep0name[] = "ep0-control"; |
159 | 166 | ||
@@ -282,8 +289,7 @@ static void s3c_hsudc_nuke_ep(struct s3c_hsudc_ep *hsep, int status) | |||
282 | * All the endpoints are stopped and any pending transfer requests if any on | 289 | * All the endpoints are stopped and any pending transfer requests if any on |
283 | * the endpoint are terminated. | 290 | * the endpoint are terminated. |
284 | */ | 291 | */ |
285 | static void s3c_hsudc_stop_activity(struct s3c_hsudc *hsudc, | 292 | static void s3c_hsudc_stop_activity(struct s3c_hsudc *hsudc) |
286 | struct usb_gadget_driver *driver) | ||
287 | { | 293 | { |
288 | struct s3c_hsudc_ep *hsep; | 294 | struct s3c_hsudc_ep *hsep; |
289 | int epnum; | 295 | int epnum; |
@@ -295,10 +301,6 @@ static void s3c_hsudc_stop_activity(struct s3c_hsudc *hsudc, | |||
295 | hsep->stopped = 1; | 301 | hsep->stopped = 1; |
296 | s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN); | 302 | s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN); |
297 | } | 303 | } |
298 | |||
299 | spin_unlock(&hsudc->lock); | ||
300 | driver->disconnect(&hsudc->gadget); | ||
301 | spin_lock(&hsudc->lock); | ||
302 | } | 304 | } |
303 | 305 | ||
304 | /** | 306 | /** |
@@ -1135,16 +1137,15 @@ static irqreturn_t s3c_hsudc_irq(int irq, void *_dev) | |||
1135 | return IRQ_HANDLED; | 1137 | return IRQ_HANDLED; |
1136 | } | 1138 | } |
1137 | 1139 | ||
1138 | static int s3c_hsudc_start(struct usb_gadget_driver *driver, | 1140 | static int s3c_hsudc_start(struct usb_gadget *gadget, |
1139 | int (*bind)(struct usb_gadget *)) | 1141 | struct usb_gadget_driver *driver) |
1140 | { | 1142 | { |
1141 | struct s3c_hsudc *hsudc = the_controller; | 1143 | struct s3c_hsudc *hsudc = to_hsudc(gadget); |
1142 | int ret; | 1144 | int ret; |
1143 | 1145 | ||
1144 | if (!driver | 1146 | if (!driver |
1145 | || driver->speed < USB_SPEED_FULL | 1147 | || driver->max_speed < USB_SPEED_FULL |
1146 | || !bind | 1148 | || !driver->setup) |
1147 | || !driver->unbind || !driver->disconnect || !driver->setup) | ||
1148 | return -EINVAL; | 1149 | return -EINVAL; |
1149 | 1150 | ||
1150 | if (!hsudc) | 1151 | if (!hsudc) |
@@ -1155,21 +1156,12 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, | |||
1155 | 1156 | ||
1156 | hsudc->driver = driver; | 1157 | hsudc->driver = driver; |
1157 | hsudc->gadget.dev.driver = &driver->driver; | 1158 | hsudc->gadget.dev.driver = &driver->driver; |
1158 | hsudc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1159 | ret = device_add(&hsudc->gadget.dev); | ||
1160 | if (ret) { | ||
1161 | dev_err(hsudc->dev, "failed to probe gadget device"); | ||
1162 | return ret; | ||
1163 | } | ||
1164 | 1159 | ||
1165 | ret = bind(&hsudc->gadget); | 1160 | ret = regulator_bulk_enable(ARRAY_SIZE(hsudc->supplies), |
1166 | if (ret) { | 1161 | hsudc->supplies); |
1167 | dev_err(hsudc->dev, "%s: bind failed\n", hsudc->gadget.name); | 1162 | if (ret != 0) { |
1168 | device_del(&hsudc->gadget.dev); | 1163 | dev_err(hsudc->dev, "failed to enable supplies: %d\n", ret); |
1169 | 1164 | goto err_supplies; | |
1170 | hsudc->driver = NULL; | ||
1171 | hsudc->gadget.dev.driver = NULL; | ||
1172 | return ret; | ||
1173 | } | 1165 | } |
1174 | 1166 | ||
1175 | /* connect to bus through transceiver */ | 1167 | /* connect to bus through transceiver */ |
@@ -1178,13 +1170,7 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, | |||
1178 | if (ret) { | 1170 | if (ret) { |
1179 | dev_err(hsudc->dev, "%s: can't bind to transceiver\n", | 1171 | dev_err(hsudc->dev, "%s: can't bind to transceiver\n", |
1180 | hsudc->gadget.name); | 1172 | hsudc->gadget.name); |
1181 | driver->unbind(&hsudc->gadget); | 1173 | goto err_otg; |
1182 | |||
1183 | device_del(&hsudc->gadget.dev); | ||
1184 | |||
1185 | hsudc->driver = NULL; | ||
1186 | hsudc->gadget.dev.driver = NULL; | ||
1187 | return ret; | ||
1188 | } | 1174 | } |
1189 | } | 1175 | } |
1190 | 1176 | ||
@@ -1197,34 +1183,43 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, | |||
1197 | hsudc->pd->gpio_init(); | 1183 | hsudc->pd->gpio_init(); |
1198 | 1184 | ||
1199 | return 0; | 1185 | return 0; |
1186 | err_otg: | ||
1187 | regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); | ||
1188 | err_supplies: | ||
1189 | hsudc->driver = NULL; | ||
1190 | hsudc->gadget.dev.driver = NULL; | ||
1191 | return ret; | ||
1200 | } | 1192 | } |
1201 | 1193 | ||
1202 | static int s3c_hsudc_stop(struct usb_gadget_driver *driver) | 1194 | static int s3c_hsudc_stop(struct usb_gadget *gadget, |
1195 | struct usb_gadget_driver *driver) | ||
1203 | { | 1196 | { |
1204 | struct s3c_hsudc *hsudc = the_controller; | 1197 | struct s3c_hsudc *hsudc = to_hsudc(gadget); |
1205 | unsigned long flags; | 1198 | unsigned long flags; |
1206 | 1199 | ||
1207 | if (!hsudc) | 1200 | if (!hsudc) |
1208 | return -ENODEV; | 1201 | return -ENODEV; |
1209 | 1202 | ||
1210 | if (!driver || driver != hsudc->driver || !driver->unbind) | 1203 | if (!driver || driver != hsudc->driver) |
1211 | return -EINVAL; | 1204 | return -EINVAL; |
1212 | 1205 | ||
1213 | spin_lock_irqsave(&hsudc->lock, flags); | 1206 | spin_lock_irqsave(&hsudc->lock, flags); |
1214 | hsudc->driver = 0; | 1207 | hsudc->driver = NULL; |
1208 | hsudc->gadget.dev.driver = NULL; | ||
1209 | hsudc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1215 | s3c_hsudc_uninit_phy(); | 1210 | s3c_hsudc_uninit_phy(); |
1216 | if (hsudc->pd->gpio_uninit) | 1211 | if (hsudc->pd->gpio_uninit) |
1217 | hsudc->pd->gpio_uninit(); | 1212 | hsudc->pd->gpio_uninit(); |
1218 | s3c_hsudc_stop_activity(hsudc, driver); | 1213 | s3c_hsudc_stop_activity(hsudc); |
1219 | spin_unlock_irqrestore(&hsudc->lock, flags); | 1214 | spin_unlock_irqrestore(&hsudc->lock, flags); |
1220 | 1215 | ||
1221 | if (hsudc->transceiver) | 1216 | if (hsudc->transceiver) |
1222 | (void) otg_set_peripheral(hsudc->transceiver, NULL); | 1217 | (void) otg_set_peripheral(hsudc->transceiver, NULL); |
1223 | 1218 | ||
1224 | driver->unbind(&hsudc->gadget); | ||
1225 | device_del(&hsudc->gadget.dev); | ||
1226 | disable_irq(hsudc->irq); | 1219 | disable_irq(hsudc->irq); |
1227 | 1220 | ||
1221 | regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); | ||
1222 | |||
1228 | dev_info(hsudc->dev, "unregistered gadget driver '%s'\n", | 1223 | dev_info(hsudc->dev, "unregistered gadget driver '%s'\n", |
1229 | driver->driver.name); | 1224 | driver->driver.name); |
1230 | return 0; | 1225 | return 0; |
@@ -1242,7 +1237,7 @@ static int s3c_hsudc_gadget_getframe(struct usb_gadget *gadget) | |||
1242 | 1237 | ||
1243 | static int s3c_hsudc_vbus_draw(struct usb_gadget *gadget, unsigned mA) | 1238 | static int s3c_hsudc_vbus_draw(struct usb_gadget *gadget, unsigned mA) |
1244 | { | 1239 | { |
1245 | struct s3c_hsudc *hsudc = the_controller; | 1240 | struct s3c_hsudc *hsudc = to_hsudc(gadget); |
1246 | 1241 | ||
1247 | if (!hsudc) | 1242 | if (!hsudc) |
1248 | return -ENODEV; | 1243 | return -ENODEV; |
@@ -1255,18 +1250,18 @@ static int s3c_hsudc_vbus_draw(struct usb_gadget *gadget, unsigned mA) | |||
1255 | 1250 | ||
1256 | static struct usb_gadget_ops s3c_hsudc_gadget_ops = { | 1251 | static struct usb_gadget_ops s3c_hsudc_gadget_ops = { |
1257 | .get_frame = s3c_hsudc_gadget_getframe, | 1252 | .get_frame = s3c_hsudc_gadget_getframe, |
1258 | .start = s3c_hsudc_start, | 1253 | .udc_start = s3c_hsudc_start, |
1259 | .stop = s3c_hsudc_stop, | 1254 | .udc_stop = s3c_hsudc_stop, |
1260 | .vbus_draw = s3c_hsudc_vbus_draw, | 1255 | .vbus_draw = s3c_hsudc_vbus_draw, |
1261 | }; | 1256 | }; |
1262 | 1257 | ||
1263 | static int s3c_hsudc_probe(struct platform_device *pdev) | 1258 | static int __devinit s3c_hsudc_probe(struct platform_device *pdev) |
1264 | { | 1259 | { |
1265 | struct device *dev = &pdev->dev; | 1260 | struct device *dev = &pdev->dev; |
1266 | struct resource *res; | 1261 | struct resource *res; |
1267 | struct s3c_hsudc *hsudc; | 1262 | struct s3c_hsudc *hsudc; |
1268 | struct s3c24xx_hsudc_platdata *pd = pdev->dev.platform_data; | 1263 | struct s3c24xx_hsudc_platdata *pd = pdev->dev.platform_data; |
1269 | int ret; | 1264 | int ret, i; |
1270 | 1265 | ||
1271 | hsudc = kzalloc(sizeof(struct s3c_hsudc) + | 1266 | hsudc = kzalloc(sizeof(struct s3c_hsudc) + |
1272 | sizeof(struct s3c_hsudc_ep) * pd->epnum, | 1267 | sizeof(struct s3c_hsudc_ep) * pd->epnum, |
@@ -1276,13 +1271,22 @@ static int s3c_hsudc_probe(struct platform_device *pdev) | |||
1276 | return -ENOMEM; | 1271 | return -ENOMEM; |
1277 | } | 1272 | } |
1278 | 1273 | ||
1279 | the_controller = hsudc; | ||
1280 | platform_set_drvdata(pdev, dev); | 1274 | platform_set_drvdata(pdev, dev); |
1281 | hsudc->dev = dev; | 1275 | hsudc->dev = dev; |
1282 | hsudc->pd = pdev->dev.platform_data; | 1276 | hsudc->pd = pdev->dev.platform_data; |
1283 | 1277 | ||
1284 | hsudc->transceiver = otg_get_transceiver(); | 1278 | hsudc->transceiver = otg_get_transceiver(); |
1285 | 1279 | ||
1280 | for (i = 0; i < ARRAY_SIZE(hsudc->supplies); i++) | ||
1281 | hsudc->supplies[i].supply = s3c_hsudc_supply_names[i]; | ||
1282 | |||
1283 | ret = regulator_bulk_get(dev, ARRAY_SIZE(hsudc->supplies), | ||
1284 | hsudc->supplies); | ||
1285 | if (ret != 0) { | ||
1286 | dev_err(dev, "failed to request supplies: %d\n", ret); | ||
1287 | goto err_supplies; | ||
1288 | } | ||
1289 | |||
1286 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1290 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1287 | if (!res) { | 1291 | if (!res) { |
1288 | dev_err(dev, "unable to obtain driver resource data\n"); | 1292 | dev_err(dev, "unable to obtain driver resource data\n"); |
@@ -1307,10 +1311,9 @@ static int s3c_hsudc_probe(struct platform_device *pdev) | |||
1307 | 1311 | ||
1308 | spin_lock_init(&hsudc->lock); | 1312 | spin_lock_init(&hsudc->lock); |
1309 | 1313 | ||
1310 | device_initialize(&hsudc->gadget.dev); | ||
1311 | dev_set_name(&hsudc->gadget.dev, "gadget"); | 1314 | dev_set_name(&hsudc->gadget.dev, "gadget"); |
1312 | 1315 | ||
1313 | hsudc->gadget.is_dualspeed = 1; | 1316 | hsudc->gadget.max_speed = USB_SPEED_HIGH; |
1314 | hsudc->gadget.ops = &s3c_hsudc_gadget_ops; | 1317 | hsudc->gadget.ops = &s3c_hsudc_gadget_ops; |
1315 | hsudc->gadget.name = dev_name(dev); | 1318 | hsudc->gadget.name = dev_name(dev); |
1316 | hsudc->gadget.dev.parent = dev; | 1319 | hsudc->gadget.dev.parent = dev; |
@@ -1319,6 +1322,7 @@ static int s3c_hsudc_probe(struct platform_device *pdev) | |||
1319 | 1322 | ||
1320 | hsudc->gadget.is_otg = 0; | 1323 | hsudc->gadget.is_otg = 0; |
1321 | hsudc->gadget.is_a_peripheral = 0; | 1324 | hsudc->gadget.is_a_peripheral = 0; |
1325 | hsudc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1322 | 1326 | ||
1323 | s3c_hsudc_setup_ep(hsudc); | 1327 | s3c_hsudc_setup_ep(hsudc); |
1324 | 1328 | ||
@@ -1348,12 +1352,20 @@ static int s3c_hsudc_probe(struct platform_device *pdev) | |||
1348 | disable_irq(hsudc->irq); | 1352 | disable_irq(hsudc->irq); |
1349 | local_irq_enable(); | 1353 | local_irq_enable(); |
1350 | 1354 | ||
1355 | ret = device_register(&hsudc->gadget.dev); | ||
1356 | if (ret) { | ||
1357 | put_device(&hsudc->gadget.dev); | ||
1358 | goto err_add_device; | ||
1359 | } | ||
1360 | |||
1351 | ret = usb_add_gadget_udc(&pdev->dev, &hsudc->gadget); | 1361 | ret = usb_add_gadget_udc(&pdev->dev, &hsudc->gadget); |
1352 | if (ret) | 1362 | if (ret) |
1353 | goto err_add_udc; | 1363 | goto err_add_udc; |
1354 | 1364 | ||
1355 | return 0; | 1365 | return 0; |
1356 | err_add_udc: | 1366 | err_add_udc: |
1367 | device_unregister(&hsudc->gadget.dev); | ||
1368 | err_add_device: | ||
1357 | clk_disable(hsudc->uclk); | 1369 | clk_disable(hsudc->uclk); |
1358 | clk_put(hsudc->uclk); | 1370 | clk_put(hsudc->uclk); |
1359 | err_clk: | 1371 | err_clk: |
@@ -1362,10 +1374,13 @@ err_irq: | |||
1362 | iounmap(hsudc->regs); | 1374 | iounmap(hsudc->regs); |
1363 | 1375 | ||
1364 | err_remap: | 1376 | err_remap: |
1365 | release_resource(hsudc->mem_rsrc); | 1377 | release_mem_region(res->start, resource_size(res)); |
1366 | kfree(hsudc->mem_rsrc); | ||
1367 | |||
1368 | err_res: | 1378 | err_res: |
1379 | if (hsudc->transceiver) | ||
1380 | otg_put_transceiver(hsudc->transceiver); | ||
1381 | |||
1382 | regulator_bulk_free(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); | ||
1383 | err_supplies: | ||
1369 | kfree(hsudc); | 1384 | kfree(hsudc); |
1370 | return ret; | 1385 | return ret; |
1371 | } | 1386 | } |
@@ -1377,21 +1392,10 @@ static struct platform_driver s3c_hsudc_driver = { | |||
1377 | }, | 1392 | }, |
1378 | .probe = s3c_hsudc_probe, | 1393 | .probe = s3c_hsudc_probe, |
1379 | }; | 1394 | }; |
1380 | MODULE_ALIAS("platform:s3c-hsudc"); | ||
1381 | |||
1382 | static int __init s3c_hsudc_modinit(void) | ||
1383 | { | ||
1384 | return platform_driver_register(&s3c_hsudc_driver); | ||
1385 | } | ||
1386 | 1395 | ||
1387 | static void __exit s3c_hsudc_modexit(void) | 1396 | module_platform_driver(s3c_hsudc_driver); |
1388 | { | ||
1389 | platform_driver_unregister(&s3c_hsudc_driver); | ||
1390 | } | ||
1391 | |||
1392 | module_init(s3c_hsudc_modinit); | ||
1393 | module_exit(s3c_hsudc_modexit); | ||
1394 | 1397 | ||
1395 | MODULE_DESCRIPTION("Samsung S3C24XX USB high-speed controller driver"); | 1398 | MODULE_DESCRIPTION("Samsung S3C24XX USB high-speed controller driver"); |
1396 | MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>"); | 1399 | MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>"); |
1397 | MODULE_LICENSE("GPL"); | 1400 | MODULE_LICENSE("GPL"); |
1401 | MODULE_ALIAS("platform:s3c-hsudc"); | ||
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index fac4c650d4bb..3f87cb9344bb 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -1683,9 +1683,9 @@ static int s3c2410_udc_start(struct usb_gadget_driver *driver, | |||
1683 | if (udc->driver) | 1683 | if (udc->driver) |
1684 | return -EBUSY; | 1684 | return -EBUSY; |
1685 | 1685 | ||
1686 | if (!bind || !driver->setup || driver->speed < USB_SPEED_FULL) { | 1686 | if (!bind || !driver->setup || driver->max_speed < USB_SPEED_FULL) { |
1687 | printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n", | 1687 | printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n", |
1688 | bind, driver->setup, driver->speed); | 1688 | bind, driver->setup, driver->max_speed); |
1689 | return -EINVAL; | 1689 | return -EINVAL; |
1690 | } | 1690 | } |
1691 | #if defined(MODULE) | 1691 | #if defined(MODULE) |
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 6939e17f4580..0b0d12ccc487 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c | |||
@@ -371,14 +371,28 @@ static ssize_t usb_udc_softconn_store(struct device *dev, | |||
371 | } | 371 | } |
372 | static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store); | 372 | static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store); |
373 | 373 | ||
374 | static ssize_t usb_udc_speed_show(struct device *dev, | 374 | #define USB_UDC_SPEED_ATTR(name, param) \ |
375 | ssize_t usb_udc_##param##_show(struct device *dev, \ | ||
376 | struct device_attribute *attr, char *buf) \ | ||
377 | { \ | ||
378 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \ | ||
379 | return snprintf(buf, PAGE_SIZE, "%s\n", \ | ||
380 | usb_speed_string(udc->gadget->param)); \ | ||
381 | } \ | ||
382 | static DEVICE_ATTR(name, S_IRUSR, usb_udc_##param##_show, NULL) | ||
383 | |||
384 | static USB_UDC_SPEED_ATTR(current_speed, speed); | ||
385 | static USB_UDC_SPEED_ATTR(maximum_speed, max_speed); | ||
386 | |||
387 | /* TODO: Scheduled for removal in 3.8. */ | ||
388 | static ssize_t usb_udc_is_dualspeed_show(struct device *dev, | ||
375 | struct device_attribute *attr, char *buf) | 389 | struct device_attribute *attr, char *buf) |
376 | { | 390 | { |
377 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); | 391 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); |
378 | return snprintf(buf, PAGE_SIZE, "%s\n", | 392 | return snprintf(buf, PAGE_SIZE, "%d\n", |
379 | usb_speed_string(udc->gadget->speed)); | 393 | gadget_is_dualspeed(udc->gadget)); |
380 | } | 394 | } |
381 | static DEVICE_ATTR(speed, S_IRUGO, usb_udc_speed_show, NULL); | 395 | static DEVICE_ATTR(is_dualspeed, S_IRUSR, usb_udc_is_dualspeed_show, NULL); |
382 | 396 | ||
383 | #define USB_UDC_ATTR(name) \ | 397 | #define USB_UDC_ATTR(name) \ |
384 | ssize_t usb_udc_##name##_show(struct device *dev, \ | 398 | ssize_t usb_udc_##name##_show(struct device *dev, \ |
@@ -391,7 +405,6 @@ ssize_t usb_udc_##name##_show(struct device *dev, \ | |||
391 | } \ | 405 | } \ |
392 | static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL) | 406 | static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL) |
393 | 407 | ||
394 | static USB_UDC_ATTR(is_dualspeed); | ||
395 | static USB_UDC_ATTR(is_otg); | 408 | static USB_UDC_ATTR(is_otg); |
396 | static USB_UDC_ATTR(is_a_peripheral); | 409 | static USB_UDC_ATTR(is_a_peripheral); |
397 | static USB_UDC_ATTR(b_hnp_enable); | 410 | static USB_UDC_ATTR(b_hnp_enable); |
@@ -401,7 +414,8 @@ static USB_UDC_ATTR(a_alt_hnp_support); | |||
401 | static struct attribute *usb_udc_attrs[] = { | 414 | static struct attribute *usb_udc_attrs[] = { |
402 | &dev_attr_srp.attr, | 415 | &dev_attr_srp.attr, |
403 | &dev_attr_soft_connect.attr, | 416 | &dev_attr_soft_connect.attr, |
404 | &dev_attr_speed.attr, | 417 | &dev_attr_current_speed.attr, |
418 | &dev_attr_maximum_speed.attr, | ||
405 | 419 | ||
406 | &dev_attr_is_dualspeed.attr, | 420 | &dev_attr_is_dualspeed.attr, |
407 | &dev_attr_is_otg.attr, | 421 | &dev_attr_is_otg.attr, |
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index 58c4d37d312a..4d25b9009edf 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c | |||
@@ -13,82 +13,17 @@ | |||
13 | #include <linux/string.h> | 13 | #include <linux/string.h> |
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/nls.h> | ||
16 | 17 | ||
17 | #include <linux/usb/ch9.h> | 18 | #include <linux/usb/ch9.h> |
18 | #include <linux/usb/gadget.h> | 19 | #include <linux/usb/gadget.h> |
19 | 20 | ||
20 | #include <asm/unaligned.h> | ||
21 | |||
22 | |||
23 | static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len) | ||
24 | { | ||
25 | int count = 0; | ||
26 | u8 c; | ||
27 | u16 uchar; | ||
28 | |||
29 | /* this insists on correct encodings, though not minimal ones. | ||
30 | * BUT it currently rejects legit 4-byte UTF-8 code points, | ||
31 | * which need surrogate pairs. (Unicode 3.1 can use them.) | ||
32 | */ | ||
33 | while (len != 0 && (c = (u8) *s++) != 0) { | ||
34 | if (unlikely(c & 0x80)) { | ||
35 | // 2-byte sequence: | ||
36 | // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx | ||
37 | if ((c & 0xe0) == 0xc0) { | ||
38 | uchar = (c & 0x1f) << 6; | ||
39 | |||
40 | c = (u8) *s++; | ||
41 | if ((c & 0xc0) != 0x80) | ||
42 | goto fail; | ||
43 | c &= 0x3f; | ||
44 | uchar |= c; | ||
45 | |||
46 | // 3-byte sequence (most CJKV characters): | ||
47 | // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx | ||
48 | } else if ((c & 0xf0) == 0xe0) { | ||
49 | uchar = (c & 0x0f) << 12; | ||
50 | |||
51 | c = (u8) *s++; | ||
52 | if ((c & 0xc0) != 0x80) | ||
53 | goto fail; | ||
54 | c &= 0x3f; | ||
55 | uchar |= c << 6; | ||
56 | |||
57 | c = (u8) *s++; | ||
58 | if ((c & 0xc0) != 0x80) | ||
59 | goto fail; | ||
60 | c &= 0x3f; | ||
61 | uchar |= c; | ||
62 | |||
63 | /* no bogus surrogates */ | ||
64 | if (0xd800 <= uchar && uchar <= 0xdfff) | ||
65 | goto fail; | ||
66 | |||
67 | // 4-byte sequence (surrogate pairs, currently rare): | ||
68 | // 11101110wwwwzzzzyy + 110111yyyyxxxxxx | ||
69 | // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx | ||
70 | // (uuuuu = wwww + 1) | ||
71 | // FIXME accept the surrogate code points (only) | ||
72 | |||
73 | } else | ||
74 | goto fail; | ||
75 | } else | ||
76 | uchar = c; | ||
77 | put_unaligned_le16(uchar, cp++); | ||
78 | count++; | ||
79 | len--; | ||
80 | } | ||
81 | return count; | ||
82 | fail: | ||
83 | return -1; | ||
84 | } | ||
85 | |||
86 | 21 | ||
87 | /** | 22 | /** |
88 | * usb_gadget_get_string - fill out a string descriptor | 23 | * usb_gadget_get_string - fill out a string descriptor |
89 | * @table: of c strings encoded using UTF-8 | 24 | * @table: of c strings encoded using UTF-8 |
90 | * @id: string id, from low byte of wValue in get string descriptor | 25 | * @id: string id, from low byte of wValue in get string descriptor |
91 | * @buf: at least 256 bytes | 26 | * @buf: at least 256 bytes, must be 16-bit aligned |
92 | * | 27 | * |
93 | * Finds the UTF-8 string matching the ID, and converts it into a | 28 | * Finds the UTF-8 string matching the ID, and converts it into a |
94 | * string descriptor in utf16-le. | 29 | * string descriptor in utf16-le. |
@@ -125,8 +60,8 @@ usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf) | |||
125 | 60 | ||
126 | /* string descriptors have length, tag, then UTF16-LE text */ | 61 | /* string descriptors have length, tag, then UTF16-LE text */ |
127 | len = min ((size_t) 126, strlen (s->s)); | 62 | len = min ((size_t) 126, strlen (s->s)); |
128 | memset (buf + 2, 0, 2 * len); /* zero all the bytes */ | 63 | len = utf8s_to_utf16s(s->s, len, UTF16_LITTLE_ENDIAN, |
129 | len = utf8_to_utf16le(s->s, (__le16 *)&buf[2], len); | 64 | (wchar_t *) &buf[2], 126); |
130 | if (len < 0) | 65 | if (len < 0) |
131 | return -EINVAL; | 66 | return -EINVAL; |
132 | buf [0] = (len + 1) * 2; | 67 | buf [0] = (len + 1) * 2; |