diff options
| -rw-r--r-- | drivers/usb/gadget/atmel_usba_udc.c | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index e756023362c2..07e5a0b5dcda 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
| @@ -649,7 +649,13 @@ static int usba_ep_disable(struct usb_ep *_ep) | |||
| 649 | 649 | ||
| 650 | if (!ep->desc) { | 650 | if (!ep->desc) { |
| 651 | spin_unlock_irqrestore(&udc->lock, flags); | 651 | spin_unlock_irqrestore(&udc->lock, flags); |
| 652 | DBG(DBG_ERR, "ep_disable: %s not enabled\n", ep->ep.name); | 652 | /* REVISIT because this driver disables endpoints in |
| 653 | * reset_all_endpoints() before calling disconnect(), | ||
| 654 | * most gadget drivers would trigger this non-error ... | ||
| 655 | */ | ||
| 656 | if (udc->gadget.speed != USB_SPEED_UNKNOWN) | ||
| 657 | DBG(DBG_ERR, "ep_disable: %s not enabled\n", | ||
| 658 | ep->ep.name); | ||
| 653 | return -EINVAL; | 659 | return -EINVAL; |
| 654 | } | 660 | } |
| 655 | ep->desc = NULL; | 661 | ep->desc = NULL; |
| @@ -1032,8 +1038,6 @@ static struct usba_udc the_udc = { | |||
| 1032 | .release = nop_release, | 1038 | .release = nop_release, |
| 1033 | }, | 1039 | }, |
| 1034 | }, | 1040 | }, |
| 1035 | |||
| 1036 | .lock = SPIN_LOCK_UNLOCKED, | ||
| 1037 | }; | 1041 | }; |
| 1038 | 1042 | ||
| 1039 | /* | 1043 | /* |
| @@ -1052,6 +1056,12 @@ static void reset_all_endpoints(struct usba_udc *udc) | |||
| 1052 | request_complete(ep, req, -ECONNRESET); | 1056 | request_complete(ep, req, -ECONNRESET); |
| 1053 | } | 1057 | } |
| 1054 | 1058 | ||
| 1059 | /* NOTE: normally, the next call to the gadget driver is in | ||
| 1060 | * charge of disabling endpoints... usually disconnect(). | ||
| 1061 | * The exception would be entering a high speed test mode. | ||
| 1062 | * | ||
| 1063 | * FIXME remove this code ... and retest thoroughly. | ||
| 1064 | */ | ||
| 1055 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { | 1065 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { |
| 1056 | if (ep->desc) { | 1066 | if (ep->desc) { |
| 1057 | spin_unlock(&udc->lock); | 1067 | spin_unlock(&udc->lock); |
| @@ -1219,7 +1229,7 @@ static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq) | |||
| 1219 | static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | 1229 | static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, |
| 1220 | struct usb_ctrlrequest *crq) | 1230 | struct usb_ctrlrequest *crq) |
| 1221 | { | 1231 | { |
| 1222 | int retval = 0;; | 1232 | int retval = 0; |
| 1223 | 1233 | ||
| 1224 | switch (crq->bRequest) { | 1234 | switch (crq->bRequest) { |
| 1225 | case USB_REQ_GET_STATUS: { | 1235 | case USB_REQ_GET_STATUS: { |
| @@ -1693,6 +1703,14 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
| 1693 | usba_writel(udc, INT_CLR, USBA_END_OF_RESET); | 1703 | usba_writel(udc, INT_CLR, USBA_END_OF_RESET); |
| 1694 | reset_all_endpoints(udc); | 1704 | reset_all_endpoints(udc); |
| 1695 | 1705 | ||
| 1706 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | ||
| 1707 | && udc->driver->disconnect) { | ||
| 1708 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1709 | spin_unlock(&udc->lock); | ||
| 1710 | udc->driver->disconnect(&udc->gadget); | ||
| 1711 | spin_lock(&udc->lock); | ||
| 1712 | } | ||
| 1713 | |||
| 1696 | if (status & USBA_HIGH_SPEED) { | 1714 | if (status & USBA_HIGH_SPEED) { |
| 1697 | DBG(DBG_BUS, "High-speed bus reset detected\n"); | 1715 | DBG(DBG_BUS, "High-speed bus reset detected\n"); |
| 1698 | udc->gadget.speed = USB_SPEED_HIGH; | 1716 | udc->gadget.speed = USB_SPEED_HIGH; |
| @@ -1716,9 +1734,13 @@ static irqreturn_t usba_udc_irq(int irq, void *devid) | |||
| 1716 | | USBA_DET_SUSPEND | 1734 | | USBA_DET_SUSPEND |
| 1717 | | USBA_END_OF_RESUME)); | 1735 | | USBA_END_OF_RESUME)); |
| 1718 | 1736 | ||
| 1737 | /* | ||
| 1738 | * Unclear why we hit this irregularly, e.g. in usbtest, | ||
| 1739 | * but it's clearly harmless... | ||
| 1740 | */ | ||
| 1719 | if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED)) | 1741 | if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED)) |
| 1720 | dev_warn(&udc->pdev->dev, | 1742 | dev_dbg(&udc->pdev->dev, |
| 1721 | "WARNING: EP0 configuration is invalid!\n"); | 1743 | "ODD: EP0 configuration is invalid!\n"); |
| 1722 | } | 1744 | } |
| 1723 | 1745 | ||
| 1724 | spin_unlock(&udc->lock); | 1746 | spin_unlock(&udc->lock); |
| @@ -1751,9 +1773,11 @@ static irqreturn_t usba_vbus_irq(int irq, void *devid) | |||
| 1751 | reset_all_endpoints(udc); | 1773 | reset_all_endpoints(udc); |
| 1752 | toggle_bias(0); | 1774 | toggle_bias(0); |
| 1753 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | 1775 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); |
| 1754 | spin_unlock(&udc->lock); | 1776 | if (udc->driver->disconnect) { |
| 1755 | udc->driver->disconnect(&udc->gadget); | 1777 | spin_unlock(&udc->lock); |
| 1756 | spin_lock(&udc->lock); | 1778 | udc->driver->disconnect(&udc->gadget); |
| 1779 | spin_lock(&udc->lock); | ||
| 1780 | } | ||
| 1757 | } | 1781 | } |
| 1758 | udc->vbus_prev = vbus; | 1782 | udc->vbus_prev = vbus; |
| 1759 | } | 1783 | } |
| @@ -1825,7 +1849,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 1825 | 1849 | ||
| 1826 | if (!udc->pdev) | 1850 | if (!udc->pdev) |
| 1827 | return -ENODEV; | 1851 | return -ENODEV; |
| 1828 | if (driver != udc->driver) | 1852 | if (driver != udc->driver || !driver->unbind) |
| 1829 | return -EINVAL; | 1853 | return -EINVAL; |
| 1830 | 1854 | ||
| 1831 | if (udc->vbus_pin != -1) | 1855 | if (udc->vbus_pin != -1) |
| @@ -1840,6 +1864,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 1840 | toggle_bias(0); | 1864 | toggle_bias(0); |
| 1841 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | 1865 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); |
| 1842 | 1866 | ||
| 1867 | if (udc->driver->disconnect) | ||
| 1868 | udc->driver->disconnect(&udc->gadget); | ||
| 1869 | |||
| 1843 | driver->unbind(&udc->gadget); | 1870 | driver->unbind(&udc->gadget); |
| 1844 | udc->gadget.dev.driver = NULL; | 1871 | udc->gadget.dev.driver = NULL; |
| 1845 | udc->driver = NULL; | 1872 | udc->driver = NULL; |
| @@ -1879,6 +1906,7 @@ static int __init usba_udc_probe(struct platform_device *pdev) | |||
| 1879 | goto err_get_hclk; | 1906 | goto err_get_hclk; |
| 1880 | } | 1907 | } |
| 1881 | 1908 | ||
| 1909 | spin_lock_init(&udc->lock); | ||
| 1882 | udc->pdev = pdev; | 1910 | udc->pdev = pdev; |
| 1883 | udc->pclk = pclk; | 1911 | udc->pclk = pclk; |
| 1884 | udc->hclk = hclk; | 1912 | udc->hclk = hclk; |
