diff options
Diffstat (limited to 'drivers/usb/musb/musb_gadget.c')
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 102 |
1 files changed, 27 insertions, 75 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 6aeb363e63e7..b67a062f556b 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -1663,8 +1663,8 @@ static void musb_pullup(struct musb *musb, int is_on) | |||
1663 | 1663 | ||
1664 | /* FIXME if on, HdrcStart; if off, HdrcStop */ | 1664 | /* FIXME if on, HdrcStart; if off, HdrcStop */ |
1665 | 1665 | ||
1666 | dev_dbg(musb->controller, "gadget %s D+ pullup %s\n", | 1666 | dev_dbg(musb->controller, "gadget D+ pullup %s\n", |
1667 | musb->gadget_driver->function, is_on ? "on" : "off"); | 1667 | is_on ? "on" : "off"); |
1668 | musb_writeb(musb->mregs, MUSB_POWER, power); | 1668 | musb_writeb(musb->mregs, MUSB_POWER, power); |
1669 | } | 1669 | } |
1670 | 1670 | ||
@@ -1710,6 +1710,11 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) | |||
1710 | return 0; | 1710 | return 0; |
1711 | } | 1711 | } |
1712 | 1712 | ||
1713 | static int musb_gadget_start(struct usb_gadget *g, | ||
1714 | struct usb_gadget_driver *driver); | ||
1715 | static int musb_gadget_stop(struct usb_gadget *g, | ||
1716 | struct usb_gadget_driver *driver); | ||
1717 | |||
1713 | static const struct usb_gadget_ops musb_gadget_operations = { | 1718 | static const struct usb_gadget_ops musb_gadget_operations = { |
1714 | .get_frame = musb_gadget_get_frame, | 1719 | .get_frame = musb_gadget_get_frame, |
1715 | .wakeup = musb_gadget_wakeup, | 1720 | .wakeup = musb_gadget_wakeup, |
@@ -1717,6 +1722,8 @@ static const struct usb_gadget_ops musb_gadget_operations = { | |||
1717 | /* .vbus_session = musb_gadget_vbus_session, */ | 1722 | /* .vbus_session = musb_gadget_vbus_session, */ |
1718 | .vbus_draw = musb_gadget_vbus_draw, | 1723 | .vbus_draw = musb_gadget_vbus_draw, |
1719 | .pullup = musb_gadget_pullup, | 1724 | .pullup = musb_gadget_pullup, |
1725 | .udc_start = musb_gadget_start, | ||
1726 | .udc_stop = musb_gadget_stop, | ||
1720 | }; | 1727 | }; |
1721 | 1728 | ||
1722 | /* ----------------------------------------------------------------------- */ | 1729 | /* ----------------------------------------------------------------------- */ |
@@ -1727,7 +1734,6 @@ static const struct usb_gadget_ops musb_gadget_operations = { | |||
1727 | * about there being only one external upstream port. It assumes | 1734 | * about there being only one external upstream port. It assumes |
1728 | * all peripheral ports are external... | 1735 | * all peripheral ports are external... |
1729 | */ | 1736 | */ |
1730 | static struct musb *the_gadget; | ||
1731 | 1737 | ||
1732 | static void musb_gadget_release(struct device *dev) | 1738 | static void musb_gadget_release(struct device *dev) |
1733 | { | 1739 | { |
@@ -1814,9 +1820,6 @@ int __init musb_gadget_setup(struct musb *musb) | |||
1814 | * musb peripherals at the same time, only the bus lock | 1820 | * musb peripherals at the same time, only the bus lock |
1815 | * is probably held. | 1821 | * is probably held. |
1816 | */ | 1822 | */ |
1817 | if (the_gadget) | ||
1818 | return -EBUSY; | ||
1819 | the_gadget = musb; | ||
1820 | 1823 | ||
1821 | musb->g.ops = &musb_gadget_operations; | 1824 | musb->g.ops = &musb_gadget_operations; |
1822 | musb->g.is_dualspeed = 1; | 1825 | musb->g.is_dualspeed = 1; |
@@ -1840,18 +1843,22 @@ int __init musb_gadget_setup(struct musb *musb) | |||
1840 | status = device_register(&musb->g.dev); | 1843 | status = device_register(&musb->g.dev); |
1841 | if (status != 0) { | 1844 | if (status != 0) { |
1842 | put_device(&musb->g.dev); | 1845 | put_device(&musb->g.dev); |
1843 | the_gadget = NULL; | 1846 | return status; |
1844 | } | 1847 | } |
1848 | status = usb_add_gadget_udc(musb->controller, &musb->g); | ||
1849 | if (status) | ||
1850 | goto err; | ||
1851 | |||
1852 | return 0; | ||
1853 | err: | ||
1854 | device_unregister(&musb->g.dev); | ||
1845 | return status; | 1855 | return status; |
1846 | } | 1856 | } |
1847 | 1857 | ||
1848 | void musb_gadget_cleanup(struct musb *musb) | 1858 | void musb_gadget_cleanup(struct musb *musb) |
1849 | { | 1859 | { |
1850 | if (musb != the_gadget) | 1860 | usb_del_gadget_udc(&musb->g); |
1851 | return; | ||
1852 | |||
1853 | device_unregister(&musb->g.dev); | 1861 | device_unregister(&musb->g.dev); |
1854 | the_gadget = NULL; | ||
1855 | } | 1862 | } |
1856 | 1863 | ||
1857 | /* | 1864 | /* |
@@ -1863,59 +1870,30 @@ void musb_gadget_cleanup(struct musb *musb) | |||
1863 | * -ENOMEM no memory to perform the operation | 1870 | * -ENOMEM no memory to perform the operation |
1864 | * | 1871 | * |
1865 | * @param driver the gadget driver | 1872 | * @param driver the gadget driver |
1866 | * @param bind the driver's bind function | ||
1867 | * @return <0 if error, 0 if everything is fine | 1873 | * @return <0 if error, 0 if everything is fine |
1868 | */ | 1874 | */ |
1869 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | 1875 | static int musb_gadget_start(struct usb_gadget *g, |
1870 | int (*bind)(struct usb_gadget *)) | 1876 | struct usb_gadget_driver *driver) |
1871 | { | 1877 | { |
1872 | struct musb *musb = the_gadget; | 1878 | struct musb *musb = gadget_to_musb(g); |
1873 | unsigned long flags; | 1879 | unsigned long flags; |
1874 | int retval = -EINVAL; | 1880 | int retval = -EINVAL; |
1875 | 1881 | ||
1876 | if (!driver | 1882 | if (driver->speed != USB_SPEED_HIGH) |
1877 | || driver->speed != USB_SPEED_HIGH | ||
1878 | || !bind || !driver->setup) | ||
1879 | goto err0; | ||
1880 | |||
1881 | /* driver must be initialized to support peripheral mode */ | ||
1882 | if (!musb) { | ||
1883 | dev_dbg(musb->controller, "no dev??\n"); | ||
1884 | retval = -ENODEV; | ||
1885 | goto err0; | 1883 | goto err0; |
1886 | } | ||
1887 | 1884 | ||
1888 | pm_runtime_get_sync(musb->controller); | 1885 | pm_runtime_get_sync(musb->controller); |
1889 | 1886 | ||
1890 | dev_dbg(musb->controller, "registering driver %s\n", driver->function); | 1887 | dev_dbg(musb->controller, "registering driver %s\n", driver->function); |
1891 | 1888 | ||
1892 | if (musb->gadget_driver) { | 1889 | musb->softconnect = 0; |
1893 | dev_dbg(musb->controller, "%s is already bound to %s\n", | ||
1894 | musb_driver_name, | ||
1895 | musb->gadget_driver->driver.name); | ||
1896 | retval = -EBUSY; | ||
1897 | goto err0; | ||
1898 | } | ||
1899 | |||
1900 | spin_lock_irqsave(&musb->lock, flags); | ||
1901 | musb->gadget_driver = driver; | 1890 | musb->gadget_driver = driver; |
1902 | musb->g.dev.driver = &driver->driver; | ||
1903 | driver->driver.bus = NULL; | ||
1904 | musb->softconnect = 1; | ||
1905 | spin_unlock_irqrestore(&musb->lock, flags); | ||
1906 | |||
1907 | retval = bind(&musb->g); | ||
1908 | if (retval) { | ||
1909 | dev_dbg(musb->controller, "bind to driver %s failed --> %d\n", | ||
1910 | driver->driver.name, retval); | ||
1911 | goto err1; | ||
1912 | } | ||
1913 | 1891 | ||
1914 | spin_lock_irqsave(&musb->lock, flags); | 1892 | spin_lock_irqsave(&musb->lock, flags); |
1893 | musb->is_active = 1; | ||
1915 | 1894 | ||
1916 | otg_set_peripheral(musb->xceiv, &musb->g); | 1895 | otg_set_peripheral(musb->xceiv, &musb->g); |
1917 | musb->xceiv->state = OTG_STATE_B_IDLE; | 1896 | musb->xceiv->state = OTG_STATE_B_IDLE; |
1918 | musb->is_active = 1; | ||
1919 | 1897 | ||
1920 | /* | 1898 | /* |
1921 | * FIXME this ignores the softconnect flag. Drivers are | 1899 | * FIXME this ignores the softconnect flag. Drivers are |
@@ -1927,8 +1905,6 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
1927 | if (!is_otg_enabled(musb)) | 1905 | if (!is_otg_enabled(musb)) |
1928 | musb_start(musb); | 1906 | musb_start(musb); |
1929 | 1907 | ||
1930 | otg_set_peripheral(musb->xceiv, &musb->g); | ||
1931 | |||
1932 | spin_unlock_irqrestore(&musb->lock, flags); | 1908 | spin_unlock_irqrestore(&musb->lock, flags); |
1933 | 1909 | ||
1934 | if (is_otg_enabled(musb)) { | 1910 | if (is_otg_enabled(musb)) { |
@@ -1960,15 +1936,9 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
1960 | err2: | 1936 | err2: |
1961 | if (!is_otg_enabled(musb)) | 1937 | if (!is_otg_enabled(musb)) |
1962 | musb_stop(musb); | 1938 | musb_stop(musb); |
1963 | |||
1964 | err1: | ||
1965 | musb->gadget_driver = NULL; | ||
1966 | musb->g.dev.driver = NULL; | ||
1967 | |||
1968 | err0: | 1939 | err0: |
1969 | return retval; | 1940 | return retval; |
1970 | } | 1941 | } |
1971 | EXPORT_SYMBOL(usb_gadget_probe_driver); | ||
1972 | 1942 | ||
1973 | static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) | 1943 | static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) |
1974 | { | 1944 | { |
@@ -2018,17 +1988,12 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) | |||
2018 | * | 1988 | * |
2019 | * @param driver the gadget driver to unregister | 1989 | * @param driver the gadget driver to unregister |
2020 | */ | 1990 | */ |
2021 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | 1991 | static int musb_gadget_stop(struct usb_gadget *g, |
1992 | struct usb_gadget_driver *driver) | ||
2022 | { | 1993 | { |
2023 | struct musb *musb = the_gadget; | 1994 | struct musb *musb = gadget_to_musb(g); |
2024 | unsigned long flags; | 1995 | unsigned long flags; |
2025 | 1996 | ||
2026 | if (!driver || !driver->unbind || !musb) | ||
2027 | return -EINVAL; | ||
2028 | |||
2029 | if (!musb->gadget_driver) | ||
2030 | return -EINVAL; | ||
2031 | |||
2032 | if (musb->xceiv->last_event == USB_EVENT_NONE) | 1997 | if (musb->xceiv->last_event == USB_EVENT_NONE) |
2033 | pm_runtime_get_sync(musb->controller); | 1998 | pm_runtime_get_sync(musb->controller); |
2034 | 1999 | ||
@@ -2039,9 +2004,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
2039 | 2004 | ||
2040 | spin_lock_irqsave(&musb->lock, flags); | 2005 | spin_lock_irqsave(&musb->lock, flags); |
2041 | 2006 | ||
2042 | #ifdef CONFIG_USB_MUSB_OTG | ||
2043 | musb_hnp_stop(musb); | 2007 | musb_hnp_stop(musb); |
2044 | #endif | ||
2045 | 2008 | ||
2046 | (void) musb_gadget_vbus_draw(&musb->g, 0); | 2009 | (void) musb_gadget_vbus_draw(&musb->g, 0); |
2047 | 2010 | ||
@@ -2051,13 +2014,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
2051 | 2014 | ||
2052 | dev_dbg(musb->controller, "unregistering driver %s\n", driver->function); | 2015 | dev_dbg(musb->controller, "unregistering driver %s\n", driver->function); |
2053 | 2016 | ||
2054 | spin_unlock_irqrestore(&musb->lock, flags); | ||
2055 | driver->unbind(&musb->g); | ||
2056 | spin_lock_irqsave(&musb->lock, flags); | ||
2057 | |||
2058 | musb->gadget_driver = NULL; | ||
2059 | musb->g.dev.driver = NULL; | ||
2060 | |||
2061 | musb->is_active = 0; | 2017 | musb->is_active = 0; |
2062 | musb_platform_try_idle(musb, 0); | 2018 | musb_platform_try_idle(musb, 0); |
2063 | spin_unlock_irqrestore(&musb->lock, flags); | 2019 | spin_unlock_irqrestore(&musb->lock, flags); |
@@ -2077,8 +2033,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
2077 | 2033 | ||
2078 | return 0; | 2034 | return 0; |
2079 | } | 2035 | } |
2080 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
2081 | |||
2082 | 2036 | ||
2083 | /* ----------------------------------------------------------------------- */ | 2037 | /* ----------------------------------------------------------------------- */ |
2084 | 2038 | ||
@@ -2164,7 +2118,6 @@ void musb_g_disconnect(struct musb *musb) | |||
2164 | 2118 | ||
2165 | switch (musb->xceiv->state) { | 2119 | switch (musb->xceiv->state) { |
2166 | default: | 2120 | default: |
2167 | #ifdef CONFIG_USB_MUSB_OTG | ||
2168 | dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n", | 2121 | dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n", |
2169 | otg_state_string(musb->xceiv->state)); | 2122 | otg_state_string(musb->xceiv->state)); |
2170 | musb->xceiv->state = OTG_STATE_A_IDLE; | 2123 | musb->xceiv->state = OTG_STATE_A_IDLE; |
@@ -2176,7 +2129,6 @@ void musb_g_disconnect(struct musb *musb) | |||
2176 | break; | 2129 | break; |
2177 | case OTG_STATE_B_WAIT_ACON: | 2130 | case OTG_STATE_B_WAIT_ACON: |
2178 | case OTG_STATE_B_HOST: | 2131 | case OTG_STATE_B_HOST: |
2179 | #endif | ||
2180 | case OTG_STATE_B_PERIPHERAL: | 2132 | case OTG_STATE_B_PERIPHERAL: |
2181 | case OTG_STATE_B_IDLE: | 2133 | case OTG_STATE_B_IDLE: |
2182 | musb->xceiv->state = OTG_STATE_B_IDLE; | 2134 | musb->xceiv->state = OTG_STATE_B_IDLE; |