Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux...
[pandora-kernel.git] / drivers / usb / gadget / ci13xxx_udc.c
index 09c76a1..baaf87e 100644 (file)
@@ -1634,8 +1634,6 @@ static int _gadget_stop_activity(struct usb_gadget *gadget)
        gadget_for_each_ep(ep, gadget) {
                usb_ep_disable(ep);
        }
-       usb_ep_disable(&udc->ep0out.ep);
-       usb_ep_disable(&udc->ep0in.ep);
 
        if (udc->status != NULL) {
                usb_ep_free_request(&udc->ep0in.ep, udc->status);
@@ -1678,18 +1676,10 @@ __acquires(udc->lock)
        if (retval)
                goto done;
 
-       retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc);
-       if (retval)
-               goto done;
+       udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC);
+       if (udc->status == NULL)
+               retval = -ENOMEM;
 
-       retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc);
-       if (!retval) {
-               udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC);
-               if (udc->status == NULL) {
-                       usb_ep_disable(&udc->ep0out.ep);
-                       retval = -ENOMEM;
-               }
-       }
        spin_lock(udc->lock);
 
  done:
@@ -2120,7 +2110,12 @@ static int ep_enable(struct usb_ep *ep,
                (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT;
        mEp->qh.ptr->td.next |= TD_TERMINATE;   /* needed? */
 
-       retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type);
+       /*
+        * Enable endpoints in the HW other than ep0 as ep0
+        * is always enabled
+        */
+       if (mEp->num)
+               retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type);
 
        spin_unlock_irqrestore(mEp->lock, flags);
        return retval;
@@ -2511,6 +2506,15 @@ out:
        return ret;
 }
 
+static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
+{
+       struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
+
+       if (udc->transceiver)
+               return otg_set_power(udc->transceiver, mA);
+       return -ENOTSUPP;
+}
+
 /**
  * Device operations part of the API to the USB controller hardware,
  * which don't involve endpoints (or i/o)
@@ -2519,6 +2523,7 @@ out:
 static const struct usb_gadget_ops usb_gadget_ops = {
        .vbus_session   = ci13xxx_vbus_session,
        .wakeup         = ci13xxx_wakeup,
+       .vbus_draw      = ci13xxx_vbus_draw,
 };
 
 /**
@@ -2609,6 +2614,14 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
        }
        if (retval)
                goto done;
+       spin_unlock_irqrestore(udc->lock, flags);
+       retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc);
+       if (retval)
+               return retval;
+       retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc);
+       if (retval)
+               return retval;
+       spin_lock_irqsave(udc->lock, flags);
 
        udc->gadget.ep0 = &udc->ep0in.ep;
        /* bind gadget */