]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/usb/gadget/r8a66597-udc.c
USB: gadget: imx_udc: Use resource size
[mv-sheeva.git] / drivers / usb / gadget / r8a66597-udc.c
index 956618400a7c6d4548eeec806b903501182c8099..e220fb8091a3618d536123f86c724d95bc7e8325 100644 (file)
@@ -614,8 +614,17 @@ static void disable_controller(struct r8a66597 *r8a66597)
        if (r8a66597->pdata->on_chip) {
                r8a66597_bset(r8a66597, SCKE, SYSCFG0);
 
+               /* disable interrupts */
                r8a66597_write(r8a66597, 0, INTENB0);
                r8a66597_write(r8a66597, 0, INTENB1);
+               r8a66597_write(r8a66597, 0, BRDYENB);
+               r8a66597_write(r8a66597, 0, BEMPENB);
+               r8a66597_write(r8a66597, 0, NRDYENB);
+
+               /* clear status */
+               r8a66597_write(r8a66597, 0, BRDYSTS);
+               r8a66597_write(r8a66597, 0, NRDYSTS);
+               r8a66597_write(r8a66597, 0, BEMPSTS);
 
                r8a66597_bclr(r8a66597, USBE, SYSCFG0);
                r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
@@ -957,8 +966,13 @@ static void clear_feature(struct r8a66597 *r8a66597,
                u16 w_index = le16_to_cpu(ctrl->wIndex);
 
                ep = r8a66597->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK];
-               pipe_stop(r8a66597, ep->pipenum);
-               control_reg_sqclr(r8a66597, ep->pipenum);
+               if (!ep->wedge) {
+                       pipe_stop(r8a66597, ep->pipenum);
+                       control_reg_sqclr(r8a66597, ep->pipenum);
+                       spin_unlock(&r8a66597->lock);
+                       usb_ep_clear_halt(&ep->ep);
+                       spin_lock(&r8a66597->lock);
+               }
 
                control_end(r8a66597, 1);
 
@@ -1331,6 +1345,7 @@ static int r8a66597_set_halt(struct usb_ep *_ep, int value)
                pipe_stall(ep->r8a66597, ep->pipenum);
        } else {
                ep->busy = 0;
+               ep->wedge = 0;
                pipe_stop(ep->r8a66597, ep->pipenum);
        }
 
@@ -1339,6 +1354,23 @@ out:
        return ret;
 }
 
+static int r8a66597_set_wedge(struct usb_ep *_ep)
+{
+       struct r8a66597_ep *ep;
+       unsigned long flags;
+
+       ep = container_of(_ep, struct r8a66597_ep, ep);
+
+       if (!ep || !ep->desc)
+               return -EINVAL;
+
+       spin_lock_irqsave(&ep->r8a66597->lock, flags);
+       ep->wedge = 1;
+       spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+
+       return usb_ep_set_halt(_ep);
+}
+
 static void r8a66597_fifo_flush(struct usb_ep *_ep)
 {
        struct r8a66597_ep *ep;
@@ -1364,6 +1396,7 @@ static struct usb_ep_ops r8a66597_ep_ops = {
        .dequeue        = r8a66597_dequeue,
 
        .set_halt       = r8a66597_set_halt,
+       .set_wedge      = r8a66597_set_wedge,
        .fifo_flush     = r8a66597_fifo_flush,
 };