aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2012-02-17 05:10:04 -0500
committerFelipe Balbi <balbi@ti.com>2012-06-06 04:22:24 -0400
commitea53b8828c50b7a5138a8931c41b2671682c86b5 (patch)
tree1e2e7c519313478a30342ed757641bbef7c21294 /drivers/usb/dwc3/gadget.c
parent6dbc10c61d5841f64945fd94977fa8fa1c0192da (diff)
usb: dwc3: gadget: don't wait for ep cmd IRQ
That IRQ is causing way too much trouble. We have a different handling which was agreed with IP provider and has been tested with FPGA and OMAP5. Tested-by: Pratyush Anand <pratyush.anand@st.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c66
1 files changed, 27 insertions, 39 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 056ace8ab97d..0f19978d4840 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -555,9 +555,34 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
555{ 555{
556 struct dwc3_request *req; 556 struct dwc3_request *req;
557 557
558 if (!list_empty(&dep->req_queued)) 558 if (!list_empty(&dep->req_queued)) {
559 dwc3_stop_active_transfer(dwc, dep->number); 559 dwc3_stop_active_transfer(dwc, dep->number);
560 560
561 /*
562 * NOTICE: We are violating what the Databook says about the
563 * EndTransfer command. Ideally we would _always_ wait for the
564 * EndTransfer Command Completion IRQ, but that's causing too
565 * much trouble synchronizing between us and gadget driver.
566 *
567 * We have discussed this with the IP Provider and it was
568 * suggested to giveback all requests here, but give HW some
569 * extra time to synchronize with the interconnect. We're using
570 * an arbitraty 100us delay for that.
571 *
572 * Note also that a similar handling was tested by Synopsys
573 * (thanks a lot Paul) and nothing bad has come out of it.
574 * In short, what we're doing is:
575 *
576 * - Issue EndTransfer WITH CMDIOC bit set
577 * - Wait 100us
578 * - giveback all requests to gadget driver
579 */
580 udelay(100);
581
582 req = next_request(&dep->req_queued);
583 dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
584 }
585
561 while (!list_empty(&dep->request_list)) { 586 while (!list_empty(&dep->request_list)) {
562 req = next_request(&dep->request_list); 587 req = next_request(&dep->request_list);
563 588
@@ -1735,43 +1760,6 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
1735 } 1760 }
1736} 1761}
1737 1762
1738static void dwc3_process_ep_cmd_complete(struct dwc3_ep *dep,
1739 const struct dwc3_event_depevt *event)
1740{
1741 struct dwc3 *dwc = dep->dwc;
1742 struct dwc3_event_depevt mod_ev = *event;
1743
1744 /*
1745 * We were asked to remove one request. It is possible that this
1746 * request and a few others were started together and have the same
1747 * transfer index. Since we stopped the complete endpoint we don't
1748 * know how many requests were already completed (and not yet)
1749 * reported and how could be done (later). We purge them all until
1750 * the end of the list.
1751 */
1752 mod_ev.status = DEPEVT_STATUS_LST;
1753 dwc3_cleanup_done_reqs(dwc, dep, &mod_ev, -ESHUTDOWN);
1754 dep->flags &= ~DWC3_EP_BUSY;
1755 /* pending requests are ignored and are queued on XferNotReady */
1756}
1757
1758static void dwc3_ep_cmd_compl(struct dwc3_ep *dep,
1759 const struct dwc3_event_depevt *event)
1760{
1761 u32 param = event->parameters;
1762 u32 cmd_type = (param >> 8) & ((1 << 5) - 1);
1763
1764 switch (cmd_type) {
1765 case DWC3_DEPCMD_ENDTRANSFER:
1766 dwc3_process_ep_cmd_complete(dep, event);
1767 break;
1768 default:
1769 printk(KERN_ERR "%s() unknown /unexpected type: %d\n",
1770 __func__, cmd_type);
1771 break;
1772 };
1773}
1774
1775static void dwc3_endpoint_interrupt(struct dwc3 *dwc, 1763static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
1776 const struct dwc3_event_depevt *event) 1764 const struct dwc3_event_depevt *event)
1777{ 1765{
@@ -1853,7 +1841,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
1853 dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name); 1841 dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name);
1854 break; 1842 break;
1855 case DWC3_DEPEVT_EPCMDCMPLT: 1843 case DWC3_DEPEVT_EPCMDCMPLT:
1856 dwc3_ep_cmd_compl(dep, event); 1844 dev_vdbg(dwc->dev, "Endpoint Command Complete\n");
1857 break; 1845 break;
1858 } 1846 }
1859} 1847}