diff options
Diffstat (limited to 'drivers/usb/gadget/fsl_udc.c')
-rw-r--r-- | drivers/usb/gadget/fsl_udc.c | 70 |
1 files changed, 23 insertions, 47 deletions
diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c index 50bae783e5..3cfeb8a510 100644 --- a/drivers/usb/gadget/fsl_udc.c +++ b/drivers/usb/gadget/fsl_udc.c @@ -1999,58 +1999,33 @@ int usb_gadget_poll(void) * Hook to gadget drivers * Called by initialization code of gadget drivers *----------------------------------------------------------------*/ -int usb_gadget_register_driver(struct usb_gadget_driver *driver) +static int fsl_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { - int retval = -ENODEV; - - if (!udc_controller) - return -ENODEV; - - if (!driver || (driver->speed != USB_SPEED_FULL - && driver->speed != USB_SPEED_HIGH) - || !driver->bind || !driver->disconnect - || !driver->setup) - return -EINVAL; - - if (udc_controller->driver) - return -EBUSY; + /* + * We currently have PHY no driver which could call vbus_connect, + * so when the USB gadget core calls usb_gadget_connect() the + * driver decides to disable the device because it has no vbus. + * Work around this by enabling vbus here. + */ + usb_gadget_vbus_connect(gadget); /* hook up the driver */ udc_controller->driver = driver; - /* bind udc driver to gadget driver */ - retval = driver->bind(&udc_controller->gadget); - if (retval) { - VDBG("bind to gadget --> %d", retval); - udc_controller->driver = NULL; - goto out; - } - /* Enable DR IRQ reg and Set usbcmd reg Run bit */ dr_controller_run(udc_controller); udc_controller->usb_state = USB_STATE_ATTACHED; udc_controller->ep0_state = WAIT_FOR_SETUP; udc_controller->ep0_dir = 0; -out: - if (retval) - printk(KERN_WARNING "gadget driver register failed %d\n", - retval); - return retval; + return 0; } -EXPORT_SYMBOL(usb_gadget_register_driver); /* Disconnect from gadget driver */ -int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +static int fsl_udc_stop(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct fsl_ep *loop_ep; - if (!udc_controller) - return -ENODEV; - - if (!driver || driver != udc_controller->driver || !driver->unbind) - return -EINVAL; - /* stop DR, disable intr */ dr_controller_stop(udc_controller); @@ -2066,16 +2041,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) ep.ep_list) nuke(loop_ep, -ESHUTDOWN); - /* report disconnect; the controller is already quiesced */ - driver->disconnect(&udc_controller->gadget); - - /* unbind gadget and unhook driver. */ - driver->unbind(&udc_controller->gadget); - udc_controller->driver = NULL; - return 0; } -EXPORT_SYMBOL(usb_gadget_unregister_driver); static int struct_udc_setup(struct fsl_udc *udc, struct device_d *dev) @@ -2202,12 +2169,14 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) udc = container_of(gadget, struct fsl_udc, gadget); udc->softconnect = (is_on != 0); - if (can_pullup(udc)) + + if (can_pullup(udc)) { writel((readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP), &dr_regs->usbcmd); - else + } else { writel((readl(&dr_regs->usbcmd) & ~USB_CMD_RUN_STOP), &dr_regs->usbcmd); + } return 0; } @@ -2220,6 +2189,8 @@ static struct usb_gadget_ops fsl_gadget_ops = { .vbus_session = fsl_vbus_session, .vbus_draw = fsl_vbus_draw, .pullup = fsl_pullup, + .udc_start = fsl_udc_start, + .udc_stop = fsl_udc_stop, }; /*---------------------------------------------------------------- @@ -2243,7 +2214,7 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, /* for ep0: maxP defined in desc * for other eps, maxP is set by epautoconfig() called by gadget layer */ - ep->ep.maxpacket = (unsigned short) ~0; + usb_ep_set_maxpacket_limit(&ep->ep, (unsigned short) ~0); /* the queue lists any req for this ep */ INIT_LIST_HEAD(&ep->queue); @@ -2300,10 +2271,10 @@ int ci_udc_register(struct device_d *dev, void __iomem *regs) /* Setup gadget structure */ udc_controller->gadget.ops = &fsl_gadget_ops; - udc_controller->gadget.is_dualspeed = 1; udc_controller->gadget.ep0 = &udc_controller->eps[0].ep; INIT_LIST_HEAD(&udc_controller->gadget.ep_list); udc_controller->gadget.speed = USB_SPEED_UNKNOWN; + udc_controller->gadget.max_speed = USB_SPEED_HIGH; udc_controller->gadget.name = "fsl-usb2-udc"; /* setup QH and epctrl for ep0 */ @@ -2330,6 +2301,11 @@ int ci_udc_register(struct device_d *dev, void __iomem *regs) poller_register(&poller); + ret = usb_add_gadget_udc_release(dev, &udc_controller->gadget, + NULL); + if (ret) + goto err_out; + return 0; err_out: return ret; |