diff options
author | Sebastian Andrzej Siewior <sebastian@breakpoint.cc> | 2012-02-04 12:55:24 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-05-04 08:53:01 -0400 |
commit | d809f78f81fc1c7e9d8afaaa51ec4813612aff94 (patch) | |
tree | 8e818679d8eabd6c26dcb55ffe0b51d4b69f3639 | |
parent | f3d8bf34c2c925867322197096ed501ceab8085a (diff) |
usb: gadget: atmel_usba_udc: convert to newstyle start/stop interface
This patches converts the driver into the new style start/stop interface.
As a result the driver no longer uses the static global the_udc
variable in start/stop functions. I kept the the_udc variable since it
makes the init code a little simpler.
Someone with hardware might want to look if it possible to move the vbus
irq/toggle_bias code into ->pullup().
Compile tested only.
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r-- | drivers/usb/gadget/atmel_usba_udc.c | 52 |
1 files changed, 12 insertions, 40 deletions
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index f545e933758f..e23bf7984aaf 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -1008,16 +1008,16 @@ usba_udc_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered) | |||
1008 | return 0; | 1008 | return 0; |
1009 | } | 1009 | } |
1010 | 1010 | ||
1011 | static int atmel_usba_start(struct usb_gadget_driver *driver, | 1011 | static int atmel_usba_start(struct usb_gadget *gadget, |
1012 | int (*bind)(struct usb_gadget *)); | 1012 | struct usb_gadget_driver *driver); |
1013 | static int atmel_usba_stop(struct usb_gadget_driver *driver); | 1013 | static int atmel_usba_stop(struct usb_gadget *gadget, |
1014 | 1014 | struct usb_gadget_driver *driver); | |
1015 | static const struct usb_gadget_ops usba_udc_ops = { | 1015 | static const struct usb_gadget_ops usba_udc_ops = { |
1016 | .get_frame = usba_udc_get_frame, | 1016 | .get_frame = usba_udc_get_frame, |
1017 | .wakeup = usba_udc_wakeup, | 1017 | .wakeup = usba_udc_wakeup, |
1018 | .set_selfpowered = usba_udc_set_selfpowered, | 1018 | .set_selfpowered = usba_udc_set_selfpowered, |
1019 | .start = atmel_usba_start, | 1019 | .udc_start = atmel_usba_start, |
1020 | .stop = atmel_usba_stop, | 1020 | .udc_stop = atmel_usba_stop, |
1021 | }; | 1021 | }; |
1022 | 1022 | ||
1023 | static struct usb_endpoint_descriptor usba_ep0_desc = { | 1023 | static struct usb_endpoint_descriptor usba_ep0_desc = { |
@@ -1795,21 +1795,13 @@ out: | |||
1795 | return IRQ_HANDLED; | 1795 | return IRQ_HANDLED; |
1796 | } | 1796 | } |
1797 | 1797 | ||
1798 | static int atmel_usba_start(struct usb_gadget_driver *driver, | 1798 | static int atmel_usba_start(struct usb_gadget *gadget, |
1799 | int (*bind)(struct usb_gadget *)) | 1799 | struct usb_gadget_driver *driver) |
1800 | { | 1800 | { |
1801 | struct usba_udc *udc = &the_udc; | 1801 | struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget); |
1802 | unsigned long flags; | 1802 | unsigned long flags; |
1803 | int ret; | ||
1804 | |||
1805 | if (!udc->pdev) | ||
1806 | return -ENODEV; | ||
1807 | 1803 | ||
1808 | spin_lock_irqsave(&udc->lock, flags); | 1804 | spin_lock_irqsave(&udc->lock, flags); |
1809 | if (udc->driver) { | ||
1810 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1811 | return -EBUSY; | ||
1812 | } | ||
1813 | 1805 | ||
1814 | udc->devstatus = 1 << USB_DEVICE_SELF_POWERED; | 1806 | udc->devstatus = 1 << USB_DEVICE_SELF_POWERED; |
1815 | udc->driver = driver; | 1807 | udc->driver = driver; |
@@ -1819,13 +1811,6 @@ static int atmel_usba_start(struct usb_gadget_driver *driver, | |||
1819 | clk_enable(udc->pclk); | 1811 | clk_enable(udc->pclk); |
1820 | clk_enable(udc->hclk); | 1812 | clk_enable(udc->hclk); |
1821 | 1813 | ||
1822 | ret = bind(&udc->gadget); | ||
1823 | if (ret) { | ||
1824 | DBG(DBG_ERR, "Could not bind to driver %s: error %d\n", | ||
1825 | driver->driver.name, ret); | ||
1826 | goto err_driver_bind; | ||
1827 | } | ||
1828 | |||
1829 | DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name); | 1814 | DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name); |
1830 | 1815 | ||
1831 | udc->vbus_prev = 0; | 1816 | udc->vbus_prev = 0; |
@@ -1842,23 +1827,14 @@ static int atmel_usba_start(struct usb_gadget_driver *driver, | |||
1842 | spin_unlock_irqrestore(&udc->lock, flags); | 1827 | spin_unlock_irqrestore(&udc->lock, flags); |
1843 | 1828 | ||
1844 | return 0; | 1829 | return 0; |
1845 | |||
1846 | err_driver_bind: | ||
1847 | udc->driver = NULL; | ||
1848 | udc->gadget.dev.driver = NULL; | ||
1849 | return ret; | ||
1850 | } | 1830 | } |
1851 | 1831 | ||
1852 | static int atmel_usba_stop(struct usb_gadget_driver *driver) | 1832 | static int atmel_usba_stop(struct usb_gadget *gadget, |
1833 | struct usb_gadget_driver *driver) | ||
1853 | { | 1834 | { |
1854 | struct usba_udc *udc = &the_udc; | 1835 | struct usba_udc *udc = container_of(gadget, struct usba_udc, gadget); |
1855 | unsigned long flags; | 1836 | unsigned long flags; |
1856 | 1837 | ||
1857 | if (!udc->pdev) | ||
1858 | return -ENODEV; | ||
1859 | if (driver != udc->driver || !driver->unbind) | ||
1860 | return -EINVAL; | ||
1861 | |||
1862 | if (gpio_is_valid(udc->vbus_pin)) | 1838 | if (gpio_is_valid(udc->vbus_pin)) |
1863 | disable_irq(gpio_to_irq(udc->vbus_pin)); | 1839 | disable_irq(gpio_to_irq(udc->vbus_pin)); |
1864 | 1840 | ||
@@ -1871,10 +1847,6 @@ static int atmel_usba_stop(struct usb_gadget_driver *driver) | |||
1871 | toggle_bias(0); | 1847 | toggle_bias(0); |
1872 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); | 1848 | usba_writel(udc, CTRL, USBA_DISABLE_MASK); |
1873 | 1849 | ||
1874 | if (udc->driver->disconnect) | ||
1875 | udc->driver->disconnect(&udc->gadget); | ||
1876 | |||
1877 | driver->unbind(&udc->gadget); | ||
1878 | udc->gadget.dev.driver = NULL; | 1850 | udc->gadget.dev.driver = NULL; |
1879 | udc->driver = NULL; | 1851 | udc->driver = NULL; |
1880 | 1852 | ||