usb: renesas_usbhs: Use dmac only if the pipe type is bulk
[firefly-linux-kernel-4.4.55.git] / drivers / usb / renesas_usbhs / mod_gadget.c
index de4f97d84a822ffd746b5550dcb68da08b581438..67f7dbda9e79576521f6d2321fd187afe63d88da 100644 (file)
@@ -131,7 +131,8 @@ static void __usbhsg_queue_pop(struct usbhsg_uep *uep,
        struct device *dev = usbhsg_gpriv_to_dev(gpriv);
        struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
 
-       dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe));
+       if (pipe)
+               dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe));
 
        ureq->req.status = status;
        spin_unlock(usbhs_priv_to_lock(priv));
@@ -157,10 +158,14 @@ static void usbhsg_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt)
        struct usbhs_pipe *pipe = pkt->pipe;
        struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe);
        struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt);
+       unsigned long flags;
 
        ureq->req.actual = pkt->actual;
 
-       usbhsg_queue_pop(uep, ureq, 0);
+       usbhs_lock(priv, flags);
+       if (uep)
+               __usbhsg_queue_pop(uep, ureq, 0);
+       usbhs_unlock(priv, flags);
 }
 
 static void usbhsg_queue_push(struct usbhsg_uep *uep,
@@ -581,6 +586,9 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
        struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
        struct usbhs_pipe *pipe;
        int ret = -EIO;
+       unsigned long flags;
+
+       usbhs_lock(priv, flags);
 
        /*
         * if it already have pipe,
@@ -589,7 +597,8 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
        if (uep->pipe) {
                usbhs_pipe_clear(uep->pipe);
                usbhs_pipe_sequence_data0(uep->pipe);
-               return 0;
+               ret = 0;
+               goto usbhsg_ep_enable_end;
        }
 
        pipe = usbhs_pipe_malloc(priv,
@@ -609,14 +618,20 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
                 * use dmaengine if possible.
                 * It will use pio handler if impossible.
                 */
-               if (usb_endpoint_dir_in(desc))
+               if (usb_endpoint_dir_in(desc)) {
                        pipe->handler = &usbhs_fifo_dma_push_handler;
-               else
+               } else {
                        pipe->handler = &usbhs_fifo_dma_pop_handler;
+                       usbhs_xxxsts_clear(priv, BRDYSTS,
+                                          usbhs_pipe_number(pipe));
+               }
 
                ret = 0;
        }
 
+usbhsg_ep_enable_end:
+       usbhs_unlock(priv, flags);
+
        return ret;
 }
 
@@ -685,7 +700,13 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
        struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
        struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
 
-       usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
+       if (pipe)
+               usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
+
+       /*
+        * To dequeue a request, this driver should call the usbhsg_queue_pop()
+        * even if the pipe is NULL.
+        */
        usbhsg_queue_pop(uep, ureq, -ECONNRESET);
 
        return 0;