diff options
author | Felipe Balbi <balbi@ti.com> | 2011-01-17 03:34:38 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2011-02-17 14:11:46 -0500 |
commit | 63eed2b52494e35aaf38ac2db537d6ea0a55b0da (patch) | |
tree | b98dace65687fd00d088df0fb5fcd25a93fa0523 | |
parent | 75a14b1434a0ca409bcc8ab9b6b2e680796c487e (diff) |
usb: musb: gadget: beautify usb_gadget_probe_driver()/usb_gadget_unregister_driver
Just a few cosmetic fixes to usb_gadget_probe_driver()
and usb_gadget_unregister_driver().
Decreased a few indentation levels with goto statements.
While at that, also add the missing call to musb_stop().
If we don't have OTG, there's no point of leaving
MUSB prepared for operation if a gadget driver fails
to probe. The same is valid for usb_gadget_unregister_driver(),
since we are removing the gadget driver and we don't have
OTG, we can completely unconfigure MUSB.
Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 150 |
1 files changed, 79 insertions, 71 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 2fe304611dcf..86decba48f28 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -1801,90 +1801,95 @@ void musb_gadget_cleanup(struct musb *musb) | |||
1801 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | 1801 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, |
1802 | int (*bind)(struct usb_gadget *)) | 1802 | int (*bind)(struct usb_gadget *)) |
1803 | { | 1803 | { |
1804 | int retval; | 1804 | struct musb *musb = the_gadget; |
1805 | unsigned long flags; | 1805 | unsigned long flags; |
1806 | struct musb *musb = the_gadget; | 1806 | int retval = -EINVAL; |
1807 | 1807 | ||
1808 | if (!driver | 1808 | if (!driver |
1809 | || driver->speed != USB_SPEED_HIGH | 1809 | || driver->speed != USB_SPEED_HIGH |
1810 | || !bind || !driver->setup) | 1810 | || !bind || !driver->setup) |
1811 | return -EINVAL; | 1811 | goto err0; |
1812 | 1812 | ||
1813 | /* driver must be initialized to support peripheral mode */ | 1813 | /* driver must be initialized to support peripheral mode */ |
1814 | if (!musb) { | 1814 | if (!musb) { |
1815 | DBG(1, "%s, no dev??\n", __func__); | 1815 | DBG(1, "%s, no dev??\n", __func__); |
1816 | return -ENODEV; | 1816 | retval = -ENODEV; |
1817 | goto err0; | ||
1817 | } | 1818 | } |
1818 | 1819 | ||
1819 | DBG(3, "registering driver %s\n", driver->function); | 1820 | DBG(3, "registering driver %s\n", driver->function); |
1820 | spin_lock_irqsave(&musb->lock, flags); | ||
1821 | 1821 | ||
1822 | if (musb->gadget_driver) { | 1822 | if (musb->gadget_driver) { |
1823 | DBG(1, "%s is already bound to %s\n", | 1823 | DBG(1, "%s is already bound to %s\n", |
1824 | musb_driver_name, | 1824 | musb_driver_name, |
1825 | musb->gadget_driver->driver.name); | 1825 | musb->gadget_driver->driver.name); |
1826 | retval = -EBUSY; | 1826 | retval = -EBUSY; |
1827 | } else { | 1827 | goto err0; |
1828 | musb->gadget_driver = driver; | ||
1829 | musb->g.dev.driver = &driver->driver; | ||
1830 | driver->driver.bus = NULL; | ||
1831 | musb->softconnect = 1; | ||
1832 | retval = 0; | ||
1833 | } | 1828 | } |
1834 | 1829 | ||
1830 | spin_lock_irqsave(&musb->lock, flags); | ||
1831 | musb->gadget_driver = driver; | ||
1832 | musb->g.dev.driver = &driver->driver; | ||
1833 | driver->driver.bus = NULL; | ||
1834 | musb->softconnect = 1; | ||
1835 | spin_unlock_irqrestore(&musb->lock, flags); | 1835 | spin_unlock_irqrestore(&musb->lock, flags); |
1836 | 1836 | ||
1837 | if (retval == 0) { | 1837 | retval = bind(&musb->g); |
1838 | retval = bind(&musb->g); | 1838 | if (retval) { |
1839 | if (retval != 0) { | 1839 | DBG(3, "bind to driver %s failed --> %d\n", |
1840 | DBG(3, "bind to driver %s failed --> %d\n", | 1840 | driver->driver.name, retval); |
1841 | driver->driver.name, retval); | 1841 | goto err1; |
1842 | musb->gadget_driver = NULL; | 1842 | } |
1843 | musb->g.dev.driver = NULL; | ||
1844 | } | ||
1845 | 1843 | ||
1846 | spin_lock_irqsave(&musb->lock, flags); | 1844 | spin_lock_irqsave(&musb->lock, flags); |
1847 | 1845 | ||
1848 | otg_set_peripheral(musb->xceiv, &musb->g); | 1846 | otg_set_peripheral(musb->xceiv, &musb->g); |
1849 | musb->xceiv->state = OTG_STATE_B_IDLE; | 1847 | musb->xceiv->state = OTG_STATE_B_IDLE; |
1850 | musb->is_active = 1; | 1848 | musb->is_active = 1; |
1851 | 1849 | ||
1852 | /* FIXME this ignores the softconnect flag. Drivers are | 1850 | /* |
1853 | * allowed hold the peripheral inactive until for example | 1851 | * FIXME this ignores the softconnect flag. Drivers are |
1854 | * userspace hooks up printer hardware or DSP codecs, so | 1852 | * allowed hold the peripheral inactive until for example |
1855 | * hosts only see fully functional devices. | 1853 | * userspace hooks up printer hardware or DSP codecs, so |
1856 | */ | 1854 | * hosts only see fully functional devices. |
1855 | */ | ||
1857 | 1856 | ||
1858 | if (!is_otg_enabled(musb)) | 1857 | if (!is_otg_enabled(musb)) |
1859 | musb_start(musb); | 1858 | musb_start(musb); |
1860 | 1859 | ||
1861 | otg_set_peripheral(musb->xceiv, &musb->g); | 1860 | otg_set_peripheral(musb->xceiv, &musb->g); |
1862 | 1861 | ||
1863 | spin_unlock_irqrestore(&musb->lock, flags); | 1862 | spin_unlock_irqrestore(&musb->lock, flags); |
1864 | 1863 | ||
1865 | if (is_otg_enabled(musb)) { | 1864 | if (is_otg_enabled(musb)) { |
1866 | struct usb_hcd *hcd = musb_to_hcd(musb); | 1865 | struct usb_hcd *hcd = musb_to_hcd(musb); |
1867 | 1866 | ||
1868 | DBG(3, "OTG startup...\n"); | 1867 | DBG(3, "OTG startup...\n"); |
1869 | 1868 | ||
1870 | /* REVISIT: funcall to other code, which also | 1869 | /* REVISIT: funcall to other code, which also |
1871 | * handles power budgeting ... this way also | 1870 | * handles power budgeting ... this way also |
1872 | * ensures HdrcStart is indirectly called. | 1871 | * ensures HdrcStart is indirectly called. |
1873 | */ | 1872 | */ |
1874 | retval = usb_add_hcd(musb_to_hcd(musb), -1, 0); | 1873 | retval = usb_add_hcd(musb_to_hcd(musb), -1, 0); |
1875 | if (retval < 0) { | 1874 | if (retval < 0) { |
1876 | DBG(1, "add_hcd failed, %d\n", retval); | 1875 | DBG(1, "add_hcd failed, %d\n", retval); |
1877 | spin_lock_irqsave(&musb->lock, flags); | 1876 | goto err2; |
1878 | otg_set_peripheral(musb->xceiv, NULL); | ||
1879 | musb->gadget_driver = NULL; | ||
1880 | musb->g.dev.driver = NULL; | ||
1881 | spin_unlock_irqrestore(&musb->lock, flags); | ||
1882 | } else { | ||
1883 | hcd->self.uses_pio_for_control = 1; | ||
1884 | } | ||
1885 | } | 1877 | } |
1878 | |||
1879 | hcd->self.uses_pio_for_control = 1; | ||
1886 | } | 1880 | } |
1887 | 1881 | ||
1882 | return 0; | ||
1883 | |||
1884 | err2: | ||
1885 | if (!is_otg_enabled(musb)) | ||
1886 | musb_stop(musb); | ||
1887 | |||
1888 | err1: | ||
1889 | musb->gadget_driver = NULL; | ||
1890 | musb->g.dev.driver = NULL; | ||
1891 | |||
1892 | err0: | ||
1888 | return retval; | 1893 | return retval; |
1889 | } | 1894 | } |
1890 | EXPORT_SYMBOL(usb_gadget_probe_driver); | 1895 | EXPORT_SYMBOL(usb_gadget_probe_driver); |
@@ -1939,14 +1944,17 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) | |||
1939 | */ | 1944 | */ |
1940 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | 1945 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) |
1941 | { | 1946 | { |
1942 | unsigned long flags; | ||
1943 | int retval = 0; | ||
1944 | struct musb *musb = the_gadget; | 1947 | struct musb *musb = the_gadget; |
1948 | unsigned long flags; | ||
1945 | 1949 | ||
1946 | if (!driver || !driver->unbind || !musb) | 1950 | if (!driver || !driver->unbind || !musb) |
1947 | return -EINVAL; | 1951 | return -EINVAL; |
1948 | 1952 | ||
1949 | /* REVISIT always use otg_set_peripheral() here too; | 1953 | if (!musb->gadget_driver) |
1954 | return -EINVAL; | ||
1955 | |||
1956 | /* | ||
1957 | * REVISIT always use otg_set_peripheral() here too; | ||
1950 | * this needs to shut down the OTG engine. | 1958 | * this needs to shut down the OTG engine. |
1951 | */ | 1959 | */ |
1952 | 1960 | ||
@@ -1956,29 +1964,26 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1956 | musb_hnp_stop(musb); | 1964 | musb_hnp_stop(musb); |
1957 | #endif | 1965 | #endif |
1958 | 1966 | ||
1959 | if (musb->gadget_driver == driver) { | 1967 | (void) musb_gadget_vbus_draw(&musb->g, 0); |
1960 | 1968 | ||
1961 | (void) musb_gadget_vbus_draw(&musb->g, 0); | 1969 | musb->xceiv->state = OTG_STATE_UNDEFINED; |
1970 | stop_activity(musb, driver); | ||
1971 | otg_set_peripheral(musb->xceiv, NULL); | ||
1962 | 1972 | ||
1963 | musb->xceiv->state = OTG_STATE_UNDEFINED; | 1973 | DBG(3, "unregistering driver %s\n", driver->function); |
1964 | stop_activity(musb, driver); | ||
1965 | otg_set_peripheral(musb->xceiv, NULL); | ||
1966 | 1974 | ||
1967 | DBG(3, "unregistering driver %s\n", driver->function); | 1975 | spin_unlock_irqrestore(&musb->lock, flags); |
1968 | spin_unlock_irqrestore(&musb->lock, flags); | 1976 | driver->unbind(&musb->g); |
1969 | driver->unbind(&musb->g); | 1977 | spin_lock_irqsave(&musb->lock, flags); |
1970 | spin_lock_irqsave(&musb->lock, flags); | ||
1971 | 1978 | ||
1972 | musb->gadget_driver = NULL; | 1979 | musb->gadget_driver = NULL; |
1973 | musb->g.dev.driver = NULL; | 1980 | musb->g.dev.driver = NULL; |
1974 | 1981 | ||
1975 | musb->is_active = 0; | 1982 | musb->is_active = 0; |
1976 | musb_platform_try_idle(musb, 0); | 1983 | musb_platform_try_idle(musb, 0); |
1977 | } else | ||
1978 | retval = -EINVAL; | ||
1979 | spin_unlock_irqrestore(&musb->lock, flags); | 1984 | spin_unlock_irqrestore(&musb->lock, flags); |
1980 | 1985 | ||
1981 | if (is_otg_enabled(musb) && retval == 0) { | 1986 | if (is_otg_enabled(musb)) { |
1982 | usb_remove_hcd(musb_to_hcd(musb)); | 1987 | usb_remove_hcd(musb_to_hcd(musb)); |
1983 | /* FIXME we need to be able to register another | 1988 | /* FIXME we need to be able to register another |
1984 | * gadget driver here and have everything work; | 1989 | * gadget driver here and have everything work; |
@@ -1986,7 +1991,10 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1986 | */ | 1991 | */ |
1987 | } | 1992 | } |
1988 | 1993 | ||
1989 | return retval; | 1994 | if (!is_otg_enabled(musb)) |
1995 | musb_stop(musb); | ||
1996 | |||
1997 | return 0; | ||
1990 | } | 1998 | } |
1991 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | 1999 | EXPORT_SYMBOL(usb_gadget_unregister_driver); |
1992 | 2000 | ||