From: Vahram Aharonyan <vahr...@synopsys.com>

Update dwc2_hsotg structure to add descriptor chains for EP 0: two DMA
descriptors for Setup phase, per one for IN/OUT data and status phases.
Add their allocation function dwc2_gadget_alloc_ctrl_desc_chains() and
its call during gadget probe.

Signed-off-by: Vahram Aharonyan <vahr...@synopsys.com>
Signed-off-by: John Youn <johny...@synopsys.com>
---
 drivers/usb/dwc2/core.h   | 13 ++++++++++++
 drivers/usb/dwc2/gadget.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 32a3cfc..26d4c17 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -884,6 +884,12 @@ struct dwc2_hregs_backup {
  * @ctrl_req:           Request for EP0 control packets.
  * @ep0_state:          EP0 control transfers state
  * @test_mode:          USB test mode requested by the host
+ * @setup_desc_dma:    EP0 setup stage desc chain DMA address
+ * @setup_desc:                EP0 setup stage desc chain pointer
+ * @ctrl_in_desc_dma:  EP0 IN data phase desc chain DMA address
+ * @ctrl_in_desc:      EP0 IN data phase desc chain pointer
+ * @ctrl_out_desc_dma: EP0 OUT data phase desc chain DMA address
+ * @ctrl_out_desc:     EP0 OUT data phase desc chain pointer
  * @eps:                The endpoints being supplied to the gadget framework
  */
 struct dwc2_hsotg {
@@ -1027,6 +1033,13 @@ struct dwc2_hsotg {
        enum dwc2_ep0_state ep0_state;
        u8 test_mode;
 
+       dma_addr_t setup_desc_dma[2];
+       struct dwc2_dma_desc *setup_desc[2];
+       dma_addr_t ctrl_in_desc_dma;
+       struct dwc2_dma_desc *ctrl_in_desc;
+       dma_addr_t ctrl_out_desc_dma;
+       struct dwc2_dma_desc *ctrl_out_desc;
+
        struct usb_gadget gadget;
        unsigned int enabled:1;
        unsigned int connected:1;
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 4013518..729bc02d 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -324,6 +324,54 @@ static void dwc2_hsotg_unmap_dma(struct dwc2_hsotg *hsotg,
        usb_gadget_unmap_request(&hsotg->gadget, req, hs_ep->dir_in);
 }
 
+/*
+ * dwc2_gadget_alloc_ctrl_desc_chains - allocate DMA descriptor chains
+ * for Control endpoint
+ * @hsotg: The device state.
+ *
+ * This function will allocate 4 descriptor chains for EP 0: 2 for
+ * Setup stage, per one for IN and OUT data/status transactions.
+ */
+static int dwc2_gadget_alloc_ctrl_desc_chains(struct dwc2_hsotg *hsotg)
+{
+       hsotg->setup_desc[0] =
+               dmam_alloc_coherent(hsotg->dev,
+                                   sizeof(struct dwc2_dma_desc),
+                                   &hsotg->setup_desc_dma[0],
+                                   GFP_KERNEL);
+       if (!hsotg->setup_desc[0])
+               goto fail;
+
+       hsotg->setup_desc[1] =
+               dmam_alloc_coherent(hsotg->dev,
+                                   sizeof(struct dwc2_dma_desc),
+                                   &hsotg->setup_desc_dma[1],
+                                   GFP_KERNEL);
+       if (!hsotg->setup_desc[1])
+               goto fail;
+
+       hsotg->ctrl_in_desc =
+               dmam_alloc_coherent(hsotg->dev,
+                                   sizeof(struct dwc2_dma_desc),
+                                   &hsotg->ctrl_in_desc_dma,
+                                   GFP_KERNEL);
+       if (!hsotg->ctrl_in_desc)
+               goto fail;
+
+       hsotg->ctrl_out_desc =
+               dmam_alloc_coherent(hsotg->dev,
+                                   sizeof(struct dwc2_dma_desc),
+                                   &hsotg->ctrl_out_desc_dma,
+                                   GFP_KERNEL);
+       if (!hsotg->ctrl_out_desc)
+               goto fail;
+
+       return 0;
+
+fail:
+       return -ENOMEM;
+}
+
 /**
  * dwc2_hsotg_write_fifo - write packet Data to the TxFIFO
  * @hsotg: The controller state.
@@ -3857,6 +3905,12 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq)
        if (!hsotg->ep0_buff)
                return -ENOMEM;
 
+       if (using_desc_dma(hsotg)) {
+               ret = dwc2_gadget_alloc_ctrl_desc_chains(hsotg);
+               if (ret < 0)
+                       return ret;
+       }
+
        ret = devm_request_irq(hsotg->dev, irq, dwc2_hsotg_irq, IRQF_SHARED,
                                dev_name(hsotg->dev), hsotg);
        if (ret < 0) {
-- 
2.10.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to