diff options
Diffstat (limited to 'drivers/usb/gadget/ci13xxx_udc.c')
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 17526759c9ce..e09178bc1450 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -1784,6 +1784,28 @@ __acquires(mEp->lock) | |||
1784 | } | 1784 | } |
1785 | 1785 | ||
1786 | /** | 1786 | /** |
1787 | * isr_setup_status_complete: setup_status request complete function | ||
1788 | * @ep: endpoint | ||
1789 | * @req: request handled | ||
1790 | * | ||
1791 | * Caller must release lock. Put the port in test mode if test mode | ||
1792 | * feature is selected. | ||
1793 | */ | ||
1794 | static void | ||
1795 | isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) | ||
1796 | { | ||
1797 | struct ci13xxx *udc = req->context; | ||
1798 | unsigned long flags; | ||
1799 | |||
1800 | trace("%p, %p", ep, req); | ||
1801 | |||
1802 | spin_lock_irqsave(udc->lock, flags); | ||
1803 | if (udc->test_mode) | ||
1804 | hw_port_test_set(udc->test_mode); | ||
1805 | spin_unlock_irqrestore(udc->lock, flags); | ||
1806 | } | ||
1807 | |||
1808 | /** | ||
1787 | * isr_setup_status_phase: queues the status phase of a setup transation | 1809 | * isr_setup_status_phase: queues the status phase of a setup transation |
1788 | * @udc: udc struct | 1810 | * @udc: udc struct |
1789 | * | 1811 | * |
@@ -1799,6 +1821,8 @@ __acquires(mEp->lock) | |||
1799 | trace("%p", udc); | 1821 | trace("%p", udc); |
1800 | 1822 | ||
1801 | mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in; | 1823 | mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in; |
1824 | udc->status->context = udc; | ||
1825 | udc->status->complete = isr_setup_status_complete; | ||
1802 | 1826 | ||
1803 | spin_unlock(mEp->lock); | 1827 | spin_unlock(mEp->lock); |
1804 | retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC); | 1828 | retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC); |
@@ -1859,6 +1883,7 @@ __releases(udc->lock) | |||
1859 | __acquires(udc->lock) | 1883 | __acquires(udc->lock) |
1860 | { | 1884 | { |
1861 | unsigned i; | 1885 | unsigned i; |
1886 | u8 tmode = 0; | ||
1862 | 1887 | ||
1863 | trace("%p", udc); | 1888 | trace("%p", udc); |
1864 | 1889 | ||
@@ -1982,14 +2007,33 @@ __acquires(udc->lock) | |||
1982 | err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); | 2007 | err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep); |
1983 | spin_lock(udc->lock); | 2008 | spin_lock(udc->lock); |
1984 | if (!err) | 2009 | if (!err) |
1985 | err = isr_setup_status_phase(udc); | 2010 | isr_setup_status_phase(udc); |
1986 | } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) && | 2011 | } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) { |
1987 | le16_to_cpu(req.wValue) == | ||
1988 | USB_DEVICE_REMOTE_WAKEUP) { | ||
1989 | if (req.wLength != 0) | 2012 | if (req.wLength != 0) |
1990 | break; | 2013 | break; |
1991 | udc->remote_wakeup = 1; | 2014 | switch (le16_to_cpu(req.wValue)) { |
1992 | err = isr_setup_status_phase(udc); | 2015 | case USB_DEVICE_REMOTE_WAKEUP: |
2016 | udc->remote_wakeup = 1; | ||
2017 | err = isr_setup_status_phase(udc); | ||
2018 | break; | ||
2019 | case USB_DEVICE_TEST_MODE: | ||
2020 | tmode = le16_to_cpu(req.wIndex) >> 8; | ||
2021 | switch (tmode) { | ||
2022 | case TEST_J: | ||
2023 | case TEST_K: | ||
2024 | case TEST_SE0_NAK: | ||
2025 | case TEST_PACKET: | ||
2026 | case TEST_FORCE_EN: | ||
2027 | udc->test_mode = tmode; | ||
2028 | err = isr_setup_status_phase( | ||
2029 | udc); | ||
2030 | break; | ||
2031 | default: | ||
2032 | break; | ||
2033 | } | ||
2034 | default: | ||
2035 | goto delegate; | ||
2036 | } | ||
1993 | } else { | 2037 | } else { |
1994 | goto delegate; | 2038 | goto delegate; |
1995 | } | 2039 | } |