diff options
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index ac3d2eec20fe..f42c29b11f71 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -574,6 +574,15 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
574 | 574 | ||
575 | if (request->actual == request->length) { | 575 | if (request->actual == request->length) { |
576 | musb_g_giveback(musb_ep, request, 0); | 576 | musb_g_giveback(musb_ep, request, 0); |
577 | /* | ||
578 | * In the giveback function the MUSB lock is | ||
579 | * released and acquired after sometime. During | ||
580 | * this time period the INDEX register could get | ||
581 | * changed by the gadget_queue function especially | ||
582 | * on SMP systems. Reselect the INDEX to be sure | ||
583 | * we are reading/modifying the right registers | ||
584 | */ | ||
585 | musb_ep_select(mbase, epnum); | ||
577 | req = musb_ep->desc ? next_request(musb_ep) : NULL; | 586 | req = musb_ep->desc ? next_request(musb_ep) : NULL; |
578 | if (!req) { | 587 | if (!req) { |
579 | dev_dbg(musb->controller, "%s idle now\n", | 588 | dev_dbg(musb->controller, "%s idle now\n", |
@@ -983,6 +992,15 @@ void musb_g_rx(struct musb *musb, u8 epnum) | |||
983 | } | 992 | } |
984 | #endif | 993 | #endif |
985 | musb_g_giveback(musb_ep, request, 0); | 994 | musb_g_giveback(musb_ep, request, 0); |
995 | /* | ||
996 | * In the giveback function the MUSB lock is | ||
997 | * released and acquired after sometime. During | ||
998 | * this time period the INDEX register could get | ||
999 | * changed by the gadget_queue function especially | ||
1000 | * on SMP systems. Reselect the INDEX to be sure | ||
1001 | * we are reading/modifying the right registers | ||
1002 | */ | ||
1003 | musb_ep_select(mbase, epnum); | ||
986 | 1004 | ||
987 | req = next_request(musb_ep); | 1005 | req = next_request(musb_ep); |
988 | if (!req) | 1006 | if (!req) |
@@ -1624,7 +1642,7 @@ static int musb_gadget_wakeup(struct usb_gadget *gadget) | |||
1624 | } | 1642 | } |
1625 | 1643 | ||
1626 | spin_unlock_irqrestore(&musb->lock, flags); | 1644 | spin_unlock_irqrestore(&musb->lock, flags); |
1627 | otg_start_srp(musb->xceiv); | 1645 | otg_start_srp(musb->xceiv->otg); |
1628 | spin_lock_irqsave(&musb->lock, flags); | 1646 | spin_lock_irqsave(&musb->lock, flags); |
1629 | 1647 | ||
1630 | /* Block idling for at least 1s */ | 1648 | /* Block idling for at least 1s */ |
@@ -1703,7 +1721,7 @@ static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) | |||
1703 | 1721 | ||
1704 | if (!musb->xceiv->set_power) | 1722 | if (!musb->xceiv->set_power) |
1705 | return -EOPNOTSUPP; | 1723 | return -EOPNOTSUPP; |
1706 | return otg_set_power(musb->xceiv, mA); | 1724 | return usb_phy_set_power(musb->xceiv, mA); |
1707 | } | 1725 | } |
1708 | 1726 | ||
1709 | static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) | 1727 | static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) |
@@ -1762,7 +1780,7 @@ static void musb_gadget_release(struct device *dev) | |||
1762 | } | 1780 | } |
1763 | 1781 | ||
1764 | 1782 | ||
1765 | static void __init | 1783 | static void __devinit |
1766 | init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) | 1784 | init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) |
1767 | { | 1785 | { |
1768 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; | 1786 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; |
@@ -1799,7 +1817,7 @@ init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) | |||
1799 | * Initialize the endpoints exposed to peripheral drivers, with backlinks | 1817 | * Initialize the endpoints exposed to peripheral drivers, with backlinks |
1800 | * to the rest of the driver state. | 1818 | * to the rest of the driver state. |
1801 | */ | 1819 | */ |
1802 | static inline void __init musb_g_init_endpoints(struct musb *musb) | 1820 | static inline void __devinit musb_g_init_endpoints(struct musb *musb) |
1803 | { | 1821 | { |
1804 | u8 epnum; | 1822 | u8 epnum; |
1805 | struct musb_hw_ep *hw_ep; | 1823 | struct musb_hw_ep *hw_ep; |
@@ -1832,7 +1850,7 @@ static inline void __init musb_g_init_endpoints(struct musb *musb) | |||
1832 | /* called once during driver setup to initialize and link into | 1850 | /* called once during driver setup to initialize and link into |
1833 | * the driver model; memory is zeroed. | 1851 | * the driver model; memory is zeroed. |
1834 | */ | 1852 | */ |
1835 | int __init musb_gadget_setup(struct musb *musb) | 1853 | int __devinit musb_gadget_setup(struct musb *musb) |
1836 | { | 1854 | { |
1837 | int status; | 1855 | int status; |
1838 | 1856 | ||
@@ -1898,6 +1916,7 @@ static int musb_gadget_start(struct usb_gadget *g, | |||
1898 | struct usb_gadget_driver *driver) | 1916 | struct usb_gadget_driver *driver) |
1899 | { | 1917 | { |
1900 | struct musb *musb = gadget_to_musb(g); | 1918 | struct musb *musb = gadget_to_musb(g); |
1919 | struct usb_otg *otg = musb->xceiv->otg; | ||
1901 | unsigned long flags; | 1920 | unsigned long flags; |
1902 | int retval = -EINVAL; | 1921 | int retval = -EINVAL; |
1903 | 1922 | ||
@@ -1914,7 +1933,7 @@ static int musb_gadget_start(struct usb_gadget *g, | |||
1914 | spin_lock_irqsave(&musb->lock, flags); | 1933 | spin_lock_irqsave(&musb->lock, flags); |
1915 | musb->is_active = 1; | 1934 | musb->is_active = 1; |
1916 | 1935 | ||
1917 | otg_set_peripheral(musb->xceiv, &musb->g); | 1936 | otg_set_peripheral(otg, &musb->g); |
1918 | musb->xceiv->state = OTG_STATE_B_IDLE; | 1937 | musb->xceiv->state = OTG_STATE_B_IDLE; |
1919 | 1938 | ||
1920 | /* | 1939 | /* |
@@ -1938,15 +1957,15 @@ static int musb_gadget_start(struct usb_gadget *g, | |||
1938 | * handles power budgeting ... this way also | 1957 | * handles power budgeting ... this way also |
1939 | * ensures HdrcStart is indirectly called. | 1958 | * ensures HdrcStart is indirectly called. |
1940 | */ | 1959 | */ |
1941 | retval = usb_add_hcd(musb_to_hcd(musb), -1, 0); | 1960 | retval = usb_add_hcd(musb_to_hcd(musb), 0, 0); |
1942 | if (retval < 0) { | 1961 | if (retval < 0) { |
1943 | dev_dbg(musb->controller, "add_hcd failed, %d\n", retval); | 1962 | dev_dbg(musb->controller, "add_hcd failed, %d\n", retval); |
1944 | goto err2; | 1963 | goto err2; |
1945 | } | 1964 | } |
1946 | 1965 | ||
1947 | if ((musb->xceiv->last_event == USB_EVENT_ID) | 1966 | if ((musb->xceiv->last_event == USB_EVENT_ID) |
1948 | && musb->xceiv->set_vbus) | 1967 | && otg->set_vbus) |
1949 | otg_set_vbus(musb->xceiv, 1); | 1968 | otg_set_vbus(otg, 1); |
1950 | 1969 | ||
1951 | hcd->self.uses_pio_for_control = 1; | 1970 | hcd->self.uses_pio_for_control = 1; |
1952 | } | 1971 | } |
@@ -2028,7 +2047,7 @@ static int musb_gadget_stop(struct usb_gadget *g, | |||
2028 | 2047 | ||
2029 | musb->xceiv->state = OTG_STATE_UNDEFINED; | 2048 | musb->xceiv->state = OTG_STATE_UNDEFINED; |
2030 | stop_activity(musb, driver); | 2049 | stop_activity(musb, driver); |
2031 | otg_set_peripheral(musb->xceiv, NULL); | 2050 | otg_set_peripheral(musb->xceiv->otg, NULL); |
2032 | 2051 | ||
2033 | dev_dbg(musb->controller, "unregistering driver %s\n", driver->function); | 2052 | dev_dbg(musb->controller, "unregistering driver %s\n", driver->function); |
2034 | 2053 | ||