diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2011-06-23 08:26:16 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-07-01 17:31:13 -0400 |
commit | e71eb392c2014e2b377810ad329e36b0229d041c (patch) | |
tree | 9fc9a4528a2af3b15ef85c8eb60fcf77c021ea34 /drivers/usb/musb | |
parent | 352c2dc8b07491bbab77ddf86c20c16a97326ee7 (diff) |
usb: musb: convert musb to new style bind
udc-core checks for valid callbacks so there is no need for the driver
to do so. Also "can-be-bound-once" is verified by udc-core. The pull-up
callback is called by udc-core afterwords.
[ balbi@ti.com : keep holding gadget_driver pointer for now
remove the stupid check for gadget_driver otherwise
we don't handle IRQs ]
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r-- | drivers/usb/musb/musb_core.c | 7 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 91 |
2 files changed, 17 insertions, 81 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 391237b0dec1..e2ab45219855 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -899,7 +899,6 @@ void musb_start(struct musb *musb) | |||
899 | 899 | ||
900 | /* put into basic highspeed mode and start session */ | 900 | /* put into basic highspeed mode and start session */ |
901 | musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE | 901 | musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE |
902 | | MUSB_POWER_SOFTCONN | ||
903 | | MUSB_POWER_HSENAB | 902 | | MUSB_POWER_HSENAB |
904 | /* ENSUSPEND wedges tusb */ | 903 | /* ENSUSPEND wedges tusb */ |
905 | /* | MUSB_POWER_ENSUSPEND */ | 904 | /* | MUSB_POWER_ENSUSPEND */ |
@@ -1526,12 +1525,6 @@ irqreturn_t musb_interrupt(struct musb *musb) | |||
1526 | (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", | 1525 | (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", |
1527 | musb->int_usb, musb->int_tx, musb->int_rx); | 1526 | musb->int_usb, musb->int_tx, musb->int_rx); |
1528 | 1527 | ||
1529 | if (is_otg_enabled(musb) || is_peripheral_enabled(musb)) | ||
1530 | if (!musb->gadget_driver) { | ||
1531 | dev_dbg(musb->controller, "No gadget driver loaded\n"); | ||
1532 | return IRQ_HANDLED; | ||
1533 | } | ||
1534 | |||
1535 | /* the core can interrupt us for multiple reasons; docs have | 1528 | /* the core can interrupt us for multiple reasons; docs have |
1536 | * a generic interrupt flowchart to follow | 1529 | * a generic interrupt flowchart to follow |
1537 | */ | 1530 | */ |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 37e70d390de8..8b626548989f 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -1657,8 +1657,8 @@ static void musb_pullup(struct musb *musb, int is_on) | |||
1657 | 1657 | ||
1658 | /* FIXME if on, HdrcStart; if off, HdrcStop */ | 1658 | /* FIXME if on, HdrcStart; if off, HdrcStop */ |
1659 | 1659 | ||
1660 | dev_dbg(musb->controller, "gadget %s D+ pullup %s\n", | 1660 | dev_dbg(musb->controller, "gadget D+ pullup %s\n", |
1661 | musb->gadget_driver->function, is_on ? "on" : "off"); | 1661 | is_on ? "on" : "off"); |
1662 | musb_writeb(musb->mregs, MUSB_POWER, power); | 1662 | musb_writeb(musb->mregs, MUSB_POWER, power); |
1663 | } | 1663 | } |
1664 | 1664 | ||
@@ -1704,9 +1704,10 @@ static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) | |||
1704 | return 0; | 1704 | return 0; |
1705 | } | 1705 | } |
1706 | 1706 | ||
1707 | static int musb_gadget_start(struct usb_gadget_driver *driver, | 1707 | static int musb_gadget_start(struct usb_gadget *g, |
1708 | int (*bind)(struct usb_gadget *)); | 1708 | struct usb_gadget_driver *driver); |
1709 | static int musb_gadget_stop(struct usb_gadget_driver *driver); | 1709 | static int musb_gadget_stop(struct usb_gadget *g, |
1710 | struct usb_gadget_driver *driver); | ||
1710 | 1711 | ||
1711 | static const struct usb_gadget_ops musb_gadget_operations = { | 1712 | static const struct usb_gadget_ops musb_gadget_operations = { |
1712 | .get_frame = musb_gadget_get_frame, | 1713 | .get_frame = musb_gadget_get_frame, |
@@ -1715,8 +1716,8 @@ static const struct usb_gadget_ops musb_gadget_operations = { | |||
1715 | /* .vbus_session = musb_gadget_vbus_session, */ | 1716 | /* .vbus_session = musb_gadget_vbus_session, */ |
1716 | .vbus_draw = musb_gadget_vbus_draw, | 1717 | .vbus_draw = musb_gadget_vbus_draw, |
1717 | .pullup = musb_gadget_pullup, | 1718 | .pullup = musb_gadget_pullup, |
1718 | .start = musb_gadget_start, | 1719 | .udc_start = musb_gadget_start, |
1719 | .stop = musb_gadget_stop, | 1720 | .udc_stop = musb_gadget_stop, |
1720 | }; | 1721 | }; |
1721 | 1722 | ||
1722 | /* ----------------------------------------------------------------------- */ | 1723 | /* ----------------------------------------------------------------------- */ |
@@ -1727,7 +1728,6 @@ static const struct usb_gadget_ops musb_gadget_operations = { | |||
1727 | * about there being only one external upstream port. It assumes | 1728 | * about there being only one external upstream port. It assumes |
1728 | * all peripheral ports are external... | 1729 | * all peripheral ports are external... |
1729 | */ | 1730 | */ |
1730 | static struct musb *the_gadget; | ||
1731 | 1731 | ||
1732 | static void musb_gadget_release(struct device *dev) | 1732 | static void musb_gadget_release(struct device *dev) |
1733 | { | 1733 | { |
@@ -1814,9 +1814,6 @@ int __init musb_gadget_setup(struct musb *musb) | |||
1814 | * musb peripherals at the same time, only the bus lock | 1814 | * musb peripherals at the same time, only the bus lock |
1815 | * is probably held. | 1815 | * is probably held. |
1816 | */ | 1816 | */ |
1817 | if (the_gadget) | ||
1818 | return -EBUSY; | ||
1819 | the_gadget = musb; | ||
1820 | 1817 | ||
1821 | musb->g.ops = &musb_gadget_operations; | 1818 | musb->g.ops = &musb_gadget_operations; |
1822 | musb->g.is_dualspeed = 1; | 1819 | musb->g.is_dualspeed = 1; |
@@ -1840,7 +1837,6 @@ int __init musb_gadget_setup(struct musb *musb) | |||
1840 | status = device_register(&musb->g.dev); | 1837 | status = device_register(&musb->g.dev); |
1841 | if (status != 0) { | 1838 | if (status != 0) { |
1842 | put_device(&musb->g.dev); | 1839 | put_device(&musb->g.dev); |
1843 | the_gadget = NULL; | ||
1844 | return status; | 1840 | return status; |
1845 | } | 1841 | } |
1846 | status = usb_add_gadget_udc(musb->controller, &musb->g); | 1842 | status = usb_add_gadget_udc(musb->controller, &musb->g); |
@@ -1850,18 +1846,13 @@ int __init musb_gadget_setup(struct musb *musb) | |||
1850 | return 0; | 1846 | return 0; |
1851 | err: | 1847 | err: |
1852 | device_unregister(&musb->g.dev); | 1848 | device_unregister(&musb->g.dev); |
1853 | the_gadget = NULL; | ||
1854 | return status; | 1849 | return status; |
1855 | } | 1850 | } |
1856 | 1851 | ||
1857 | void musb_gadget_cleanup(struct musb *musb) | 1852 | void musb_gadget_cleanup(struct musb *musb) |
1858 | { | 1853 | { |
1859 | if (musb != the_gadget) | ||
1860 | return; | ||
1861 | |||
1862 | usb_del_gadget_udc(&musb->g); | 1854 | usb_del_gadget_udc(&musb->g); |
1863 | device_unregister(&musb->g.dev); | 1855 | device_unregister(&musb->g.dev); |
1864 | the_gadget = NULL; | ||
1865 | } | 1856 | } |
1866 | 1857 | ||
1867 | /* | 1858 | /* |
@@ -1873,59 +1864,30 @@ void musb_gadget_cleanup(struct musb *musb) | |||
1873 | * -ENOMEM no memory to perform the operation | 1864 | * -ENOMEM no memory to perform the operation |
1874 | * | 1865 | * |
1875 | * @param driver the gadget driver | 1866 | * @param driver the gadget driver |
1876 | * @param bind the driver's bind function | ||
1877 | * @return <0 if error, 0 if everything is fine | 1867 | * @return <0 if error, 0 if everything is fine |
1878 | */ | 1868 | */ |
1879 | static int musb_gadget_start(struct usb_gadget_driver *driver, | 1869 | static int musb_gadget_start(struct usb_gadget *g, |
1880 | int (*bind)(struct usb_gadget *)) | 1870 | struct usb_gadget_driver *driver) |
1881 | { | 1871 | { |
1882 | struct musb *musb = the_gadget; | 1872 | struct musb *musb = gadget_to_musb(g); |
1883 | unsigned long flags; | 1873 | unsigned long flags; |
1884 | int retval = -EINVAL; | 1874 | int retval = -EINVAL; |
1885 | 1875 | ||
1886 | if (!driver | 1876 | if (driver->speed != USB_SPEED_HIGH) |
1887 | || driver->speed != USB_SPEED_HIGH | ||
1888 | || !bind || !driver->setup) | ||
1889 | goto err0; | 1877 | goto err0; |
1890 | 1878 | ||
1891 | /* driver must be initialized to support peripheral mode */ | ||
1892 | if (!musb) { | ||
1893 | dev_dbg(musb->controller, "no dev??\n"); | ||
1894 | retval = -ENODEV; | ||
1895 | goto err0; | ||
1896 | } | ||
1897 | |||
1898 | pm_runtime_get_sync(musb->controller); | 1879 | pm_runtime_get_sync(musb->controller); |
1899 | 1880 | ||
1900 | dev_dbg(musb->controller, "registering driver %s\n", driver->function); | 1881 | dev_dbg(musb->controller, "registering driver %s\n", driver->function); |
1901 | 1882 | ||
1902 | if (musb->gadget_driver) { | 1883 | musb->softconnect = 0; |
1903 | dev_dbg(musb->controller, "%s is already bound to %s\n", | ||
1904 | musb_driver_name, | ||
1905 | musb->gadget_driver->driver.name); | ||
1906 | retval = -EBUSY; | ||
1907 | goto err0; | ||
1908 | } | ||
1909 | |||
1910 | spin_lock_irqsave(&musb->lock, flags); | ||
1911 | musb->gadget_driver = driver; | 1884 | musb->gadget_driver = driver; |
1912 | musb->g.dev.driver = &driver->driver; | ||
1913 | driver->driver.bus = NULL; | ||
1914 | musb->softconnect = 1; | ||
1915 | spin_unlock_irqrestore(&musb->lock, flags); | ||
1916 | |||
1917 | retval = bind(&musb->g); | ||
1918 | if (retval) { | ||
1919 | dev_dbg(musb->controller, "bind to driver %s failed --> %d\n", | ||
1920 | driver->driver.name, retval); | ||
1921 | goto err1; | ||
1922 | } | ||
1923 | 1885 | ||
1924 | spin_lock_irqsave(&musb->lock, flags); | 1886 | spin_lock_irqsave(&musb->lock, flags); |
1887 | musb->is_active = 1; | ||
1925 | 1888 | ||
1926 | otg_set_peripheral(musb->xceiv, &musb->g); | 1889 | otg_set_peripheral(musb->xceiv, &musb->g); |
1927 | musb->xceiv->state = OTG_STATE_B_IDLE; | 1890 | musb->xceiv->state = OTG_STATE_B_IDLE; |
1928 | musb->is_active = 1; | ||
1929 | 1891 | ||
1930 | /* | 1892 | /* |
1931 | * FIXME this ignores the softconnect flag. Drivers are | 1893 | * FIXME this ignores the softconnect flag. Drivers are |
@@ -1937,8 +1899,6 @@ static int musb_gadget_start(struct usb_gadget_driver *driver, | |||
1937 | if (!is_otg_enabled(musb)) | 1899 | if (!is_otg_enabled(musb)) |
1938 | musb_start(musb); | 1900 | musb_start(musb); |
1939 | 1901 | ||
1940 | otg_set_peripheral(musb->xceiv, &musb->g); | ||
1941 | |||
1942 | spin_unlock_irqrestore(&musb->lock, flags); | 1902 | spin_unlock_irqrestore(&musb->lock, flags); |
1943 | 1903 | ||
1944 | if (is_otg_enabled(musb)) { | 1904 | if (is_otg_enabled(musb)) { |
@@ -1970,11 +1930,6 @@ static int musb_gadget_start(struct usb_gadget_driver *driver, | |||
1970 | err2: | 1930 | err2: |
1971 | if (!is_otg_enabled(musb)) | 1931 | if (!is_otg_enabled(musb)) |
1972 | musb_stop(musb); | 1932 | musb_stop(musb); |
1973 | |||
1974 | err1: | ||
1975 | musb->gadget_driver = NULL; | ||
1976 | musb->g.dev.driver = NULL; | ||
1977 | |||
1978 | err0: | 1933 | err0: |
1979 | return retval; | 1934 | return retval; |
1980 | } | 1935 | } |
@@ -2027,17 +1982,12 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) | |||
2027 | * | 1982 | * |
2028 | * @param driver the gadget driver to unregister | 1983 | * @param driver the gadget driver to unregister |
2029 | */ | 1984 | */ |
2030 | static int musb_gadget_stop(struct usb_gadget_driver *driver) | 1985 | static int musb_gadget_stop(struct usb_gadget *g, |
1986 | struct usb_gadget_driver *driver) | ||
2031 | { | 1987 | { |
2032 | struct musb *musb = the_gadget; | 1988 | struct musb *musb = gadget_to_musb(g); |
2033 | unsigned long flags; | 1989 | unsigned long flags; |
2034 | 1990 | ||
2035 | if (!driver || !driver->unbind || !musb) | ||
2036 | return -EINVAL; | ||
2037 | |||
2038 | if (!musb->gadget_driver) | ||
2039 | return -EINVAL; | ||
2040 | |||
2041 | if (musb->xceiv->last_event == USB_EVENT_NONE) | 1991 | if (musb->xceiv->last_event == USB_EVENT_NONE) |
2042 | pm_runtime_get_sync(musb->controller); | 1992 | pm_runtime_get_sync(musb->controller); |
2043 | 1993 | ||
@@ -2058,13 +2008,6 @@ static int musb_gadget_stop(struct usb_gadget_driver *driver) | |||
2058 | 2008 | ||
2059 | dev_dbg(musb->controller, "unregistering driver %s\n", driver->function); | 2009 | dev_dbg(musb->controller, "unregistering driver %s\n", driver->function); |
2060 | 2010 | ||
2061 | spin_unlock_irqrestore(&musb->lock, flags); | ||
2062 | driver->unbind(&musb->g); | ||
2063 | spin_lock_irqsave(&musb->lock, flags); | ||
2064 | |||
2065 | musb->gadget_driver = NULL; | ||
2066 | musb->g.dev.driver = NULL; | ||
2067 | |||
2068 | musb->is_active = 0; | 2011 | musb->is_active = 0; |
2069 | musb_platform_try_idle(musb, 0); | 2012 | musb_platform_try_idle(musb, 0); |
2070 | spin_unlock_irqrestore(&musb->lock, flags); | 2013 | spin_unlock_irqrestore(&musb->lock, flags); |