diff options
Diffstat (limited to 'drivers/usb/gadget/goku_udc.c')
-rw-r--r-- | drivers/usb/gadget/goku_udc.c | 70 |
1 files changed, 14 insertions, 56 deletions
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 51037cb78604..85742d4c67df 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -993,14 +993,15 @@ static int goku_get_frame(struct usb_gadget *_gadget) | |||
993 | return -EOPNOTSUPP; | 993 | return -EOPNOTSUPP; |
994 | } | 994 | } |
995 | 995 | ||
996 | static int goku_start(struct usb_gadget_driver *driver, | 996 | static int goku_udc_start(struct usb_gadget *g, |
997 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)); | 997 | struct usb_gadget_driver *driver); |
998 | static int goku_stop(struct usb_gadget_driver *driver); | 998 | static int goku_udc_stop(struct usb_gadget *g, |
999 | struct usb_gadget_driver *driver); | ||
999 | 1000 | ||
1000 | static const struct usb_gadget_ops goku_ops = { | 1001 | static const struct usb_gadget_ops goku_ops = { |
1001 | .get_frame = goku_get_frame, | 1002 | .get_frame = goku_get_frame, |
1002 | .start = goku_start, | 1003 | .udc_start = goku_udc_start, |
1003 | .stop = goku_stop, | 1004 | .udc_stop = goku_udc_stop, |
1004 | // no remote wakeup | 1005 | // no remote wakeup |
1005 | // not selfpowered | 1006 | // not selfpowered |
1006 | }; | 1007 | }; |
@@ -1339,50 +1340,28 @@ static void udc_enable(struct goku_udc *dev) | |||
1339 | * - one function driver, initted second | 1340 | * - one function driver, initted second |
1340 | */ | 1341 | */ |
1341 | 1342 | ||
1342 | static struct goku_udc *the_controller; | ||
1343 | |||
1344 | /* when a driver is successfully registered, it will receive | 1343 | /* when a driver is successfully registered, it will receive |
1345 | * control requests including set_configuration(), which enables | 1344 | * control requests including set_configuration(), which enables |
1346 | * non-control requests. then usb traffic follows until a | 1345 | * non-control requests. then usb traffic follows until a |
1347 | * disconnect is reported. then a host may connect again, or | 1346 | * disconnect is reported. then a host may connect again, or |
1348 | * the driver might get unbound. | 1347 | * the driver might get unbound. |
1349 | */ | 1348 | */ |
1350 | static int goku_start(struct usb_gadget_driver *driver, | 1349 | static int goku_udc_start(struct usb_gadget *g, |
1351 | int (*bind)(struct usb_gadget *, struct usb_gadget_driver *)) | 1350 | struct usb_gadget_driver *driver) |
1352 | { | 1351 | { |
1353 | struct goku_udc *dev = the_controller; | 1352 | struct goku_udc *dev = to_goku_udc(g); |
1354 | int retval; | ||
1355 | |||
1356 | if (!driver | ||
1357 | || driver->max_speed < USB_SPEED_FULL | ||
1358 | || !bind | ||
1359 | || !driver->disconnect | ||
1360 | || !driver->setup) | ||
1361 | return -EINVAL; | ||
1362 | if (!dev) | ||
1363 | return -ENODEV; | ||
1364 | if (dev->driver) | ||
1365 | return -EBUSY; | ||
1366 | 1353 | ||
1367 | /* hook up the driver */ | 1354 | /* hook up the driver */ |
1368 | driver->driver.bus = NULL; | 1355 | driver->driver.bus = NULL; |
1369 | dev->driver = driver; | 1356 | dev->driver = driver; |
1370 | dev->gadget.dev.driver = &driver->driver; | 1357 | dev->gadget.dev.driver = &driver->driver; |
1371 | retval = bind(&dev->gadget, driver); | ||
1372 | if (retval) { | ||
1373 | DBG(dev, "bind to driver %s --> error %d\n", | ||
1374 | driver->driver.name, retval); | ||
1375 | dev->driver = NULL; | ||
1376 | dev->gadget.dev.driver = NULL; | ||
1377 | return retval; | ||
1378 | } | ||
1379 | 1358 | ||
1380 | /* then enable host detection and ep0; and we're ready | 1359 | /* |
1360 | * then enable host detection and ep0; and we're ready | ||
1381 | * for set_configuration as well as eventual disconnect. | 1361 | * for set_configuration as well as eventual disconnect. |
1382 | */ | 1362 | */ |
1383 | udc_enable(dev); | 1363 | udc_enable(dev); |
1384 | 1364 | ||
1385 | DBG(dev, "registered gadget driver '%s'\n", driver->driver.name); | ||
1386 | return 0; | 1365 | return 0; |
1387 | } | 1366 | } |
1388 | 1367 | ||
@@ -1400,35 +1379,23 @@ stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver) | |||
1400 | udc_reset (dev); | 1379 | udc_reset (dev); |
1401 | for (i = 0; i < 4; i++) | 1380 | for (i = 0; i < 4; i++) |
1402 | nuke(&dev->ep [i], -ESHUTDOWN); | 1381 | nuke(&dev->ep [i], -ESHUTDOWN); |
1403 | if (driver) { | ||
1404 | spin_unlock(&dev->lock); | ||
1405 | driver->disconnect(&dev->gadget); | ||
1406 | spin_lock(&dev->lock); | ||
1407 | } | ||
1408 | 1382 | ||
1409 | if (dev->driver) | 1383 | if (dev->driver) |
1410 | udc_enable(dev); | 1384 | udc_enable(dev); |
1411 | } | 1385 | } |
1412 | 1386 | ||
1413 | static int goku_stop(struct usb_gadget_driver *driver) | 1387 | static int goku_udc_stop(struct usb_gadget *g, |
1388 | struct usb_gadget_driver *driver) | ||
1414 | { | 1389 | { |
1415 | struct goku_udc *dev = the_controller; | 1390 | struct goku_udc *dev = to_goku_udc(g); |
1416 | unsigned long flags; | 1391 | unsigned long flags; |
1417 | 1392 | ||
1418 | if (!dev) | ||
1419 | return -ENODEV; | ||
1420 | if (!driver || driver != dev->driver || !driver->unbind) | ||
1421 | return -EINVAL; | ||
1422 | |||
1423 | spin_lock_irqsave(&dev->lock, flags); | 1393 | spin_lock_irqsave(&dev->lock, flags); |
1424 | dev->driver = NULL; | 1394 | dev->driver = NULL; |
1425 | stop_activity(dev, driver); | 1395 | stop_activity(dev, driver); |
1426 | spin_unlock_irqrestore(&dev->lock, flags); | 1396 | spin_unlock_irqrestore(&dev->lock, flags); |
1427 | |||
1428 | driver->unbind(&dev->gadget); | ||
1429 | dev->gadget.dev.driver = NULL; | 1397 | dev->gadget.dev.driver = NULL; |
1430 | 1398 | ||
1431 | DBG(dev, "unregistered driver '%s'\n", driver->driver.name); | ||
1432 | return 0; | 1399 | return 0; |
1433 | } | 1400 | } |
1434 | 1401 | ||
@@ -1754,7 +1721,6 @@ static void goku_remove(struct pci_dev *pdev) | |||
1754 | 1721 | ||
1755 | pci_set_drvdata(pdev, NULL); | 1722 | pci_set_drvdata(pdev, NULL); |
1756 | dev->regs = NULL; | 1723 | dev->regs = NULL; |
1757 | the_controller = NULL; | ||
1758 | 1724 | ||
1759 | INFO(dev, "unbind\n"); | 1725 | INFO(dev, "unbind\n"); |
1760 | } | 1726 | } |
@@ -1770,13 +1736,6 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1770 | void __iomem *base = NULL; | 1736 | void __iomem *base = NULL; |
1771 | int retval; | 1737 | int retval; |
1772 | 1738 | ||
1773 | /* if you want to support more than one controller in a system, | ||
1774 | * usb_gadget_driver_{register,unregister}() must change. | ||
1775 | */ | ||
1776 | if (the_controller) { | ||
1777 | pr_warning("ignoring %s\n", pci_name(pdev)); | ||
1778 | return -EBUSY; | ||
1779 | } | ||
1780 | if (!pdev->irq) { | 1739 | if (!pdev->irq) { |
1781 | printk(KERN_ERR "Check PCI %s IRQ setup!\n", pci_name(pdev)); | 1740 | printk(KERN_ERR "Check PCI %s IRQ setup!\n", pci_name(pdev)); |
1782 | retval = -ENODEV; | 1741 | retval = -ENODEV; |
@@ -1851,7 +1810,6 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1851 | create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev); | 1810 | create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev); |
1852 | #endif | 1811 | #endif |
1853 | 1812 | ||
1854 | the_controller = dev; | ||
1855 | retval = device_register(&dev->gadget.dev); | 1813 | retval = device_register(&dev->gadget.dev); |
1856 | if (retval) { | 1814 | if (retval) { |
1857 | put_device(&dev->gadget.dev); | 1815 | put_device(&dev->gadget.dev); |