Hi, On Wed, Jun 06, 2012 at 04:21:59PM +0800, Yu Xu wrote: > +static int mv_u3d_start(struct usb_gadget *g, > + struct usb_gadget_driver *driver) > +{ > + struct mv_u3d *u3d = container_of(g, struct mv_u3d, gadget); > + unsigned long flags; > + > + if (u3d->driver) > + return -EBUSY; > + > + spin_lock_irqsave(&u3d->lock, flags); > + > + /* hook up the driver ... */ > + driver->driver.bus = NULL; > + u3d->driver = driver; > + u3d->gadget.dev.driver = &driver->driver; > + > + u3d->ep0_dir = USB_DIR_OUT; > + > + spin_unlock_irqrestore(&u3d->lock, flags); > + > + u3d->vbus_valid_detect = 1; > + > + return 0; > +} > + > +static int mv_u3d_stop(struct usb_gadget *g, > + struct usb_gadget_driver *driver) > +{ > + struct mv_u3d *u3d = container_of(g, struct mv_u3d, gadget); > + unsigned long flags; > + > + u3d->vbus_valid_detect = 0; > + spin_lock_irqsave(&u3d->lock, flags); > + > + mv_u3d_enable(u3d); > + mv_u3d_controller_stop(u3d); > + /* stop all usb activities */ > + u3d->gadget.speed = USB_SPEED_UNKNOWN; > + mv_u3d_stop_activity(u3d, driver); > + mv_u3d_disable(u3d); > + > + spin_unlock_irqrestore(&u3d->lock, flags); > + > + u3d->gadget.dev.driver = NULL; > + u3d->driver = NULL; > + > + return 0; > +} the whole idea of udc_start() and udc_stop() is that you only power up your controller when you know that you will need it. So on driver probe you shouldn't really enable your clocks or configure anything and instead, should move it all here. This is exactly the place you know your controller will be needed, because you're probing a gadget driver. Other that that, it's all good. -- balbi
Attachment:
signature.asc
Description: Digital signature