]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/usb/gadget/udc/renesas_usb3.c
usb: gadget: udc: renesas_usb3: Fix usb_gadget_giveback_request() calling
[karo-tx-linux.git] / drivers / usb / gadget / udc / renesas_usb3.c
index d8278322d5ac1b4fafca40af9b757016be40b0ce..e1de8fe599a35695eceda22d3138492af8995b20 100644 (file)
@@ -89,6 +89,9 @@
 
 /* USB_COM_CON */
 #define USB_COM_CON_CONF               BIT(24)
+#define USB_COM_CON_PN_WDATAIF_NL      BIT(23)
+#define USB_COM_CON_PN_RDATAIF_NL      BIT(22)
+#define USB_COM_CON_PN_LSTTR_PP                BIT(21)
 #define USB_COM_CON_SPD_MODE           BIT(17)
 #define USB_COM_CON_EP0_EN             BIT(16)
 #define USB_COM_CON_DEV_ADDR_SHIFT     8
@@ -686,6 +689,9 @@ static void renesas_usb3_init_controller(struct renesas_usb3 *usb3)
 {
        usb3_init_axi_bridge(usb3);
        usb3_init_epc_registers(usb3);
+       usb3_set_bit(usb3, USB_COM_CON_PN_WDATAIF_NL |
+                    USB_COM_CON_PN_RDATAIF_NL | USB_COM_CON_PN_LSTTR_PP,
+                    USB3_USB_COM_CON);
        usb3_write(usb3, USB_OTG_IDMON, USB3_USB_OTG_INT_STA);
        usb3_write(usb3, USB_OTG_IDMON, USB3_USB_OTG_INT_ENA);
 
@@ -832,21 +838,32 @@ static struct renesas_usb3_request *usb3_get_request(struct renesas_usb3_ep
        return usb3_req;
 }
 
-static void usb3_request_done(struct renesas_usb3_ep *usb3_ep,
-                             struct renesas_usb3_request *usb3_req, int status)
+static void __usb3_request_done(struct renesas_usb3_ep *usb3_ep,
+                               struct renesas_usb3_request *usb3_req,
+                               int status)
 {
        struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep);
-       unsigned long flags;
 
        dev_dbg(usb3_to_dev(usb3), "giveback: ep%2d, %u, %u, %d\n",
                usb3_ep->num, usb3_req->req.length, usb3_req->req.actual,
                status);
        usb3_req->req.status = status;
-       spin_lock_irqsave(&usb3->lock, flags);
        usb3_ep->started = false;
        list_del_init(&usb3_req->queue);
-       spin_unlock_irqrestore(&usb3->lock, flags);
+       spin_unlock(&usb3->lock);
        usb_gadget_giveback_request(&usb3_ep->ep, &usb3_req->req);
+       spin_lock(&usb3->lock);
+}
+
+static void usb3_request_done(struct renesas_usb3_ep *usb3_ep,
+                             struct renesas_usb3_request *usb3_req, int status)
+{
+       struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep);
+       unsigned long flags;
+
+       spin_lock_irqsave(&usb3->lock, flags);
+       __usb3_request_done(usb3_ep, usb3_req, status);
+       spin_unlock_irqrestore(&usb3->lock, flags);
 }
 
 static void usb3_irq_epc_pipe0_status_end(struct renesas_usb3 *usb3)
@@ -1369,7 +1386,7 @@ static int renesas_usb3_dma_free_prd(struct renesas_usb3 *usb3,
 
        usb3_for_each_dma(usb3, dma, i) {
                if (dma->prd) {
-                       dma_free_coherent(dev, USB3_DMA_MAX_XFER_SIZE,
+                       dma_free_coherent(dev, USB3_DMA_PRD_SIZE,
                                          dma->prd, dma->prd_dma);
                        dma->prd = NULL;
                }
@@ -1409,12 +1426,12 @@ static void usb3_start_pipen(struct renesas_usb3_ep *usb3_ep,
        int ret = -EAGAIN;
        u32 enable_bits = 0;
 
+       spin_lock_irqsave(&usb3->lock, flags);
        if (usb3_ep->halt || usb3_ep->started)
-               return;
+               goto out;
        if (usb3_req != usb3_req_first)
-               return;
+               goto out;
 
-       spin_lock_irqsave(&usb3->lock, flags);
        if (usb3_pn_change(usb3, usb3_ep->num) < 0)
                goto out;