diff options
Diffstat (limited to 'drivers/usb/gadget/langwell_udc.c')
-rw-r--r-- | drivers/usb/gadget/langwell_udc.c | 147 |
1 files changed, 46 insertions, 101 deletions
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index ff4d40d77c30..c9fa3bf5b377 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c | |||
@@ -5,16 +5,6 @@ | |||
5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms and conditions of the GNU General Public License, | 6 | * under the terms and conditions of the GNU General Public License, |
7 | * version 2, as published by the Free Software Foundation. | 7 | * version 2, as published by the Free Software Foundation. |
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | */ | 8 | */ |
19 | 9 | ||
20 | 10 | ||
@@ -60,9 +50,6 @@ static const char driver_name[] = "langwell_udc"; | |||
60 | static const char driver_desc[] = DRIVER_DESC; | 50 | static const char driver_desc[] = DRIVER_DESC; |
61 | 51 | ||
62 | 52 | ||
63 | /* controller device global variable */ | ||
64 | static struct langwell_udc *the_controller; | ||
65 | |||
66 | /* for endpoint 0 operations */ | 53 | /* for endpoint 0 operations */ |
67 | static const struct usb_endpoint_descriptor | 54 | static const struct usb_endpoint_descriptor |
68 | langwell_ep0_desc = { | 55 | langwell_ep0_desc = { |
@@ -283,7 +270,7 @@ static int langwell_ep_enable(struct usb_ep *_ep, | |||
283 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | 270 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) |
284 | return -ESHUTDOWN; | 271 | return -ESHUTDOWN; |
285 | 272 | ||
286 | max = le16_to_cpu(desc->wMaxPacketSize); | 273 | max = usb_endpoint_maxp(desc); |
287 | 274 | ||
288 | /* | 275 | /* |
289 | * disable HW zero length termination select | 276 | * disable HW zero length termination select |
@@ -1321,9 +1308,12 @@ static int langwell_pullup(struct usb_gadget *_gadget, int is_on) | |||
1321 | return 0; | 1308 | return 0; |
1322 | } | 1309 | } |
1323 | 1310 | ||
1324 | static int langwell_start(struct usb_gadget_driver *driver, | 1311 | static int langwell_start(struct usb_gadget *g, |
1325 | int (*bind)(struct usb_gadget *)); | 1312 | struct usb_gadget_driver *driver); |
1326 | static int langwell_stop(struct usb_gadget_driver *driver); | 1313 | |
1314 | static int langwell_stop(struct usb_gadget *g, | ||
1315 | struct usb_gadget_driver *driver); | ||
1316 | |||
1327 | /* device controller usb_gadget_ops structure */ | 1317 | /* device controller usb_gadget_ops structure */ |
1328 | static const struct usb_gadget_ops langwell_ops = { | 1318 | static const struct usb_gadget_ops langwell_ops = { |
1329 | 1319 | ||
@@ -1345,8 +1335,8 @@ static const struct usb_gadget_ops langwell_ops = { | |||
1345 | /* D+ pullup, software-controlled connect/disconnect to USB host */ | 1335 | /* D+ pullup, software-controlled connect/disconnect to USB host */ |
1346 | .pullup = langwell_pullup, | 1336 | .pullup = langwell_pullup, |
1347 | 1337 | ||
1348 | .start = langwell_start, | 1338 | .udc_start = langwell_start, |
1349 | .stop = langwell_stop, | 1339 | .udc_stop = langwell_stop, |
1350 | }; | 1340 | }; |
1351 | 1341 | ||
1352 | 1342 | ||
@@ -1561,7 +1551,7 @@ static void stop_activity(struct langwell_udc *dev, | |||
1561 | static ssize_t show_function(struct device *_dev, | 1551 | static ssize_t show_function(struct device *_dev, |
1562 | struct device_attribute *attr, char *buf) | 1552 | struct device_attribute *attr, char *buf) |
1563 | { | 1553 | { |
1564 | struct langwell_udc *dev = the_controller; | 1554 | struct langwell_udc *dev = dev_get_drvdata(_dev); |
1565 | 1555 | ||
1566 | if (!dev->driver || !dev->driver->function | 1556 | if (!dev->driver || !dev->driver->function |
1567 | || strlen(dev->driver->function) > PAGE_SIZE) | 1557 | || strlen(dev->driver->function) > PAGE_SIZE) |
@@ -1572,11 +1562,25 @@ static ssize_t show_function(struct device *_dev, | |||
1572 | static DEVICE_ATTR(function, S_IRUGO, show_function, NULL); | 1562 | static DEVICE_ATTR(function, S_IRUGO, show_function, NULL); |
1573 | 1563 | ||
1574 | 1564 | ||
1565 | static inline enum usb_device_speed lpm_device_speed(u32 reg) | ||
1566 | { | ||
1567 | switch (LPM_PSPD(reg)) { | ||
1568 | case LPM_SPEED_HIGH: | ||
1569 | return USB_SPEED_HIGH; | ||
1570 | case LPM_SPEED_FULL: | ||
1571 | return USB_SPEED_FULL; | ||
1572 | case LPM_SPEED_LOW: | ||
1573 | return USB_SPEED_LOW; | ||
1574 | default: | ||
1575 | return USB_SPEED_UNKNOWN; | ||
1576 | } | ||
1577 | } | ||
1578 | |||
1575 | /* device "langwell_udc" sysfs attribute file */ | 1579 | /* device "langwell_udc" sysfs attribute file */ |
1576 | static ssize_t show_langwell_udc(struct device *_dev, | 1580 | static ssize_t show_langwell_udc(struct device *_dev, |
1577 | struct device_attribute *attr, char *buf) | 1581 | struct device_attribute *attr, char *buf) |
1578 | { | 1582 | { |
1579 | struct langwell_udc *dev = the_controller; | 1583 | struct langwell_udc *dev = dev_get_drvdata(_dev); |
1580 | struct langwell_request *req; | 1584 | struct langwell_request *req; |
1581 | struct langwell_ep *ep = NULL; | 1585 | struct langwell_ep *ep = NULL; |
1582 | char *next; | 1586 | char *next; |
@@ -1700,20 +1704,7 @@ static ssize_t show_langwell_udc(struct device *_dev, | |||
1700 | "BmAttributes: %d\n\n", | 1704 | "BmAttributes: %d\n\n", |
1701 | LPM_PTS(tmp_reg), | 1705 | LPM_PTS(tmp_reg), |
1702 | (tmp_reg & LPM_STS) ? 1 : 0, | 1706 | (tmp_reg & LPM_STS) ? 1 : 0, |
1703 | ({ | 1707 | usb_speed_string(lpm_device_speed(tmp_reg)), |
1704 | char *s; | ||
1705 | switch (LPM_PSPD(tmp_reg)) { | ||
1706 | case LPM_SPEED_FULL: | ||
1707 | s = "Full Speed"; break; | ||
1708 | case LPM_SPEED_LOW: | ||
1709 | s = "Low Speed"; break; | ||
1710 | case LPM_SPEED_HIGH: | ||
1711 | s = "High Speed"; break; | ||
1712 | default: | ||
1713 | s = "Unknown Speed"; break; | ||
1714 | } | ||
1715 | s; | ||
1716 | }), | ||
1717 | (tmp_reg & LPM_PFSC) ? "Force Full Speed" : "Not Force", | 1708 | (tmp_reg & LPM_PFSC) ? "Force Full Speed" : "Not Force", |
1718 | (tmp_reg & LPM_PHCD) ? "Disabled" : "Enabled", | 1709 | (tmp_reg & LPM_PHCD) ? "Disabled" : "Enabled", |
1719 | LPM_BA(tmp_reg)); | 1710 | LPM_BA(tmp_reg)); |
@@ -1821,7 +1812,7 @@ static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL); | |||
1821 | static ssize_t store_remote_wakeup(struct device *_dev, | 1812 | static ssize_t store_remote_wakeup(struct device *_dev, |
1822 | struct device_attribute *attr, const char *buf, size_t count) | 1813 | struct device_attribute *attr, const char *buf, size_t count) |
1823 | { | 1814 | { |
1824 | struct langwell_udc *dev = the_controller; | 1815 | struct langwell_udc *dev = dev_get_drvdata(_dev); |
1825 | unsigned long flags; | 1816 | unsigned long flags; |
1826 | ssize_t rc = count; | 1817 | ssize_t rc = count; |
1827 | 1818 | ||
@@ -1857,21 +1848,15 @@ static DEVICE_ATTR(remote_wakeup, S_IWUSR, NULL, store_remote_wakeup); | |||
1857 | * the driver might get unbound. | 1848 | * the driver might get unbound. |
1858 | */ | 1849 | */ |
1859 | 1850 | ||
1860 | static int langwell_start(struct usb_gadget_driver *driver, | 1851 | static int langwell_start(struct usb_gadget *g, |
1861 | int (*bind)(struct usb_gadget *)) | 1852 | struct usb_gadget_driver *driver) |
1862 | { | 1853 | { |
1863 | struct langwell_udc *dev = the_controller; | 1854 | struct langwell_udc *dev = gadget_to_langwell(g); |
1864 | unsigned long flags; | 1855 | unsigned long flags; |
1865 | int retval; | 1856 | int retval; |
1866 | 1857 | ||
1867 | if (!dev) | ||
1868 | return -ENODEV; | ||
1869 | |||
1870 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 1858 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
1871 | 1859 | ||
1872 | if (dev->driver) | ||
1873 | return -EBUSY; | ||
1874 | |||
1875 | spin_lock_irqsave(&dev->lock, flags); | 1860 | spin_lock_irqsave(&dev->lock, flags); |
1876 | 1861 | ||
1877 | /* hook up the driver ... */ | 1862 | /* hook up the driver ... */ |
@@ -1881,18 +1866,9 @@ static int langwell_start(struct usb_gadget_driver *driver, | |||
1881 | 1866 | ||
1882 | spin_unlock_irqrestore(&dev->lock, flags); | 1867 | spin_unlock_irqrestore(&dev->lock, flags); |
1883 | 1868 | ||
1884 | retval = bind(&dev->gadget); | ||
1885 | if (retval) { | ||
1886 | dev_dbg(&dev->pdev->dev, "bind to driver %s --> %d\n", | ||
1887 | driver->driver.name, retval); | ||
1888 | dev->driver = NULL; | ||
1889 | dev->gadget.dev.driver = NULL; | ||
1890 | return retval; | ||
1891 | } | ||
1892 | |||
1893 | retval = device_create_file(&dev->pdev->dev, &dev_attr_function); | 1869 | retval = device_create_file(&dev->pdev->dev, &dev_attr_function); |
1894 | if (retval) | 1870 | if (retval) |
1895 | goto err_unbind; | 1871 | goto err; |
1896 | 1872 | ||
1897 | dev->usb_state = USB_STATE_ATTACHED; | 1873 | dev->usb_state = USB_STATE_ATTACHED; |
1898 | dev->ep0_state = WAIT_FOR_SETUP; | 1874 | dev->ep0_state = WAIT_FOR_SETUP; |
@@ -1909,31 +1885,27 @@ static int langwell_start(struct usb_gadget_driver *driver, | |||
1909 | dev_info(&dev->pdev->dev, "register driver: %s\n", | 1885 | dev_info(&dev->pdev->dev, "register driver: %s\n", |
1910 | driver->driver.name); | 1886 | driver->driver.name); |
1911 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | 1887 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); |
1888 | |||
1912 | return 0; | 1889 | return 0; |
1913 | 1890 | ||
1914 | err_unbind: | 1891 | err: |
1915 | driver->unbind(&dev->gadget); | ||
1916 | dev->gadget.dev.driver = NULL; | 1892 | dev->gadget.dev.driver = NULL; |
1917 | dev->driver = NULL; | 1893 | dev->driver = NULL; |
1918 | 1894 | ||
1919 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | 1895 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); |
1896 | |||
1920 | return retval; | 1897 | return retval; |
1921 | } | 1898 | } |
1922 | 1899 | ||
1923 | /* unregister gadget driver */ | 1900 | /* unregister gadget driver */ |
1924 | static int langwell_stop(struct usb_gadget_driver *driver) | 1901 | static int langwell_stop(struct usb_gadget *g, |
1902 | struct usb_gadget_driver *driver) | ||
1925 | { | 1903 | { |
1926 | struct langwell_udc *dev = the_controller; | 1904 | struct langwell_udc *dev = gadget_to_langwell(g); |
1927 | unsigned long flags; | 1905 | unsigned long flags; |
1928 | 1906 | ||
1929 | if (!dev) | ||
1930 | return -ENODEV; | ||
1931 | |||
1932 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 1907 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
1933 | 1908 | ||
1934 | if (unlikely(!driver || !driver->unbind)) | ||
1935 | return -EINVAL; | ||
1936 | |||
1937 | /* exit PHY low power suspend */ | 1909 | /* exit PHY low power suspend */ |
1938 | if (dev->pdev->device != 0x0829) | 1910 | if (dev->pdev->device != 0x0829) |
1939 | langwell_phy_low_power(dev, 0); | 1911 | langwell_phy_low_power(dev, 0); |
@@ -1956,8 +1928,6 @@ static int langwell_stop(struct usb_gadget_driver *driver) | |||
1956 | stop_activity(dev, driver); | 1928 | stop_activity(dev, driver); |
1957 | spin_unlock_irqrestore(&dev->lock, flags); | 1929 | spin_unlock_irqrestore(&dev->lock, flags); |
1958 | 1930 | ||
1959 | /* unbind gadget driver */ | ||
1960 | driver->unbind(&dev->gadget); | ||
1961 | dev->gadget.dev.driver = NULL; | 1931 | dev->gadget.dev.driver = NULL; |
1962 | dev->driver = NULL; | 1932 | dev->driver = NULL; |
1963 | 1933 | ||
@@ -1966,6 +1936,7 @@ static int langwell_stop(struct usb_gadget_driver *driver) | |||
1966 | dev_info(&dev->pdev->dev, "unregistered driver '%s'\n", | 1936 | dev_info(&dev->pdev->dev, "unregistered driver '%s'\n", |
1967 | driver->driver.name); | 1937 | driver->driver.name); |
1968 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); | 1938 | dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); |
1939 | |||
1969 | return 0; | 1940 | return 0; |
1970 | } | 1941 | } |
1971 | 1942 | ||
@@ -2657,12 +2628,10 @@ done: | |||
2657 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); | 2628 | dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); |
2658 | } | 2629 | } |
2659 | 2630 | ||
2660 | |||
2661 | /* port change detect interrupt handler */ | 2631 | /* port change detect interrupt handler */ |
2662 | static void handle_port_change(struct langwell_udc *dev) | 2632 | static void handle_port_change(struct langwell_udc *dev) |
2663 | { | 2633 | { |
2664 | u32 portsc1, devlc; | 2634 | u32 portsc1, devlc; |
2665 | u32 speed; | ||
2666 | 2635 | ||
2667 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | 2636 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); |
2668 | 2637 | ||
@@ -2677,24 +2646,9 @@ static void handle_port_change(struct langwell_udc *dev) | |||
2677 | /* bus reset is finished */ | 2646 | /* bus reset is finished */ |
2678 | if (!(portsc1 & PORTS_PR)) { | 2647 | if (!(portsc1 & PORTS_PR)) { |
2679 | /* get the speed */ | 2648 | /* get the speed */ |
2680 | speed = LPM_PSPD(devlc); | 2649 | dev->gadget.speed = lpm_device_speed(devlc); |
2681 | switch (speed) { | 2650 | dev_vdbg(&dev->pdev->dev, "dev->gadget.speed = %d\n", |
2682 | case LPM_SPEED_HIGH: | 2651 | dev->gadget.speed); |
2683 | dev->gadget.speed = USB_SPEED_HIGH; | ||
2684 | break; | ||
2685 | case LPM_SPEED_FULL: | ||
2686 | dev->gadget.speed = USB_SPEED_FULL; | ||
2687 | break; | ||
2688 | case LPM_SPEED_LOW: | ||
2689 | dev->gadget.speed = USB_SPEED_LOW; | ||
2690 | break; | ||
2691 | default: | ||
2692 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
2693 | break; | ||
2694 | } | ||
2695 | dev_vdbg(&dev->pdev->dev, | ||
2696 | "speed = %d, dev->gadget.speed = %d\n", | ||
2697 | speed, dev->gadget.speed); | ||
2698 | } | 2652 | } |
2699 | 2653 | ||
2700 | /* LPM L0 to L1 */ | 2654 | /* LPM L0 to L1 */ |
@@ -2999,7 +2953,7 @@ static irqreturn_t langwell_irq(int irq, void *_dev) | |||
2999 | /* release device structure */ | 2953 | /* release device structure */ |
3000 | static void gadget_release(struct device *_dev) | 2954 | static void gadget_release(struct device *_dev) |
3001 | { | 2955 | { |
3002 | struct langwell_udc *dev = the_controller; | 2956 | struct langwell_udc *dev = dev_get_drvdata(_dev); |
3003 | 2957 | ||
3004 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 2958 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
3005 | 2959 | ||
@@ -3057,7 +3011,7 @@ static void sram_deinit(struct langwell_udc *dev) | |||
3057 | /* tear down the binding between this driver and the pci device */ | 3011 | /* tear down the binding between this driver and the pci device */ |
3058 | static void langwell_udc_remove(struct pci_dev *pdev) | 3012 | static void langwell_udc_remove(struct pci_dev *pdev) |
3059 | { | 3013 | { |
3060 | struct langwell_udc *dev = the_controller; | 3014 | struct langwell_udc *dev = pci_get_drvdata(pdev); |
3061 | 3015 | ||
3062 | DECLARE_COMPLETION(done); | 3016 | DECLARE_COMPLETION(done); |
3063 | 3017 | ||
@@ -3124,8 +3078,6 @@ static void langwell_udc_remove(struct pci_dev *pdev) | |||
3124 | 3078 | ||
3125 | /* free dev, wait for the release() finished */ | 3079 | /* free dev, wait for the release() finished */ |
3126 | wait_for_completion(&done); | 3080 | wait_for_completion(&done); |
3127 | |||
3128 | the_controller = NULL; | ||
3129 | } | 3081 | } |
3130 | 3082 | ||
3131 | 3083 | ||
@@ -3144,11 +3096,6 @@ static int langwell_udc_probe(struct pci_dev *pdev, | |||
3144 | size_t size; | 3096 | size_t size; |
3145 | int retval; | 3097 | int retval; |
3146 | 3098 | ||
3147 | if (the_controller) { | ||
3148 | dev_warn(&pdev->dev, "ignoring\n"); | ||
3149 | return -EBUSY; | ||
3150 | } | ||
3151 | |||
3152 | /* alloc, and start init */ | 3099 | /* alloc, and start init */ |
3153 | dev = kzalloc(sizeof *dev, GFP_KERNEL); | 3100 | dev = kzalloc(sizeof *dev, GFP_KERNEL); |
3154 | if (dev == NULL) { | 3101 | if (dev == NULL) { |
@@ -3368,8 +3315,6 @@ static int langwell_udc_probe(struct pci_dev *pdev, | |||
3368 | "After langwell_udc_probe(), print all registers:\n"); | 3315 | "After langwell_udc_probe(), print all registers:\n"); |
3369 | print_all_registers(dev); | 3316 | print_all_registers(dev); |
3370 | 3317 | ||
3371 | the_controller = dev; | ||
3372 | |||
3373 | retval = device_register(&dev->gadget.dev); | 3318 | retval = device_register(&dev->gadget.dev); |
3374 | if (retval) | 3319 | if (retval) |
3375 | goto error; | 3320 | goto error; |
@@ -3404,7 +3349,7 @@ error: | |||
3404 | /* device controller suspend */ | 3349 | /* device controller suspend */ |
3405 | static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) | 3350 | static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) |
3406 | { | 3351 | { |
3407 | struct langwell_udc *dev = the_controller; | 3352 | struct langwell_udc *dev = pci_get_drvdata(pdev); |
3408 | 3353 | ||
3409 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 3354 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
3410 | 3355 | ||
@@ -3452,7 +3397,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3452 | /* device controller resume */ | 3397 | /* device controller resume */ |
3453 | static int langwell_udc_resume(struct pci_dev *pdev) | 3398 | static int langwell_udc_resume(struct pci_dev *pdev) |
3454 | { | 3399 | { |
3455 | struct langwell_udc *dev = the_controller; | 3400 | struct langwell_udc *dev = pci_get_drvdata(pdev); |
3456 | size_t size; | 3401 | size_t size; |
3457 | 3402 | ||
3458 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 3403 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |
@@ -3534,7 +3479,7 @@ static int langwell_udc_resume(struct pci_dev *pdev) | |||
3534 | /* pci driver shutdown */ | 3479 | /* pci driver shutdown */ |
3535 | static void langwell_udc_shutdown(struct pci_dev *pdev) | 3480 | static void langwell_udc_shutdown(struct pci_dev *pdev) |
3536 | { | 3481 | { |
3537 | struct langwell_udc *dev = the_controller; | 3482 | struct langwell_udc *dev = pci_get_drvdata(pdev); |
3538 | u32 usbmode; | 3483 | u32 usbmode; |
3539 | 3484 | ||
3540 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); | 3485 | dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); |