summaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2011-09-30 09:58:47 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2011-10-04 19:25:54 +0200
commit879631aa658be2c1307758223b6d15236f9f6335 (patch)
tree9ab6eafbe5cee1b6d57492e42ddef317a800c469 /drivers/usb/dwc3/gadget.c
parentusb: dwc3: gadget: add support for Bursts (diff)
downloadlinux-879631aa658be2c1307758223b6d15236f9f6335.tar.xz
linux-879631aa658be2c1307758223b6d15236f9f6335.zip
usb: dwc3: gadget: implement streams support
The following patch adds support for streams to dwc3 driver. While at that, also fix one small issue on endpoint disable where we should clear all flags not only ENABLED. Reviewied-by: Paul Zimmerman <paulz@synopsys.com> Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 524ff91bf393..8d8502373db6 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -264,6 +264,12 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
params.param1.depcfg.xfer_complete_enable = true;
params.param1.depcfg.xfer_not_ready_enable = true;
+ if (usb_endpoint_xfer_bulk(desc) && dep->endpoint.max_streams) {
+ params.param1.depcfg.stream_capable = true;
+ params.param1.depcfg.stream_event_enable = true;
+ dep->stream_capable = true;
+ }
+
if (usb_endpoint_xfer_isoc(desc))
params.param1.depcfg.xfer_in_progress_enable = true;
@@ -391,15 +397,16 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
struct dwc3 *dwc = dep->dwc;
u32 reg;
- dep->flags &= ~DWC3_EP_ENABLED;
dwc3_remove_requests(dwc, dep);
reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
reg &= ~DWC3_DALEPENA_EP(dep->number);
dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
+ dep->stream_capable = false;
dep->desc = NULL;
dep->type = 0;
+ dep->flags = 0;
return 0;
}
@@ -633,6 +640,9 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
trb.lst = last_one;
}
+ if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
+ trb.sid_sofn = req->request.stream_id;
+
switch (usb_endpoint_type(dep->desc)) {
case USB_ENDPOINT_XFER_CONTROL:
trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;
@@ -1505,12 +1515,28 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
}
break;
+ case DWC3_DEPEVT_STREAMEVT:
+ if (!usb_endpoint_xfer_bulk(dep->desc)) {
+ dev_err(dwc->dev, "Stream event for non-Bulk %s\n",
+ dep->name);
+ return;
+ }
+
+ switch (event->status) {
+ case DEPEVT_STREAMEVT_FOUND:
+ dev_vdbg(dwc->dev, "Stream %d found and started\n",
+ event->parameters);
+
+ break;
+ case DEPEVT_STREAMEVT_NOTFOUND:
+ /* FALLTHROUGH */
+ default:
+ dev_dbg(dwc->dev, "Couldn't find suitable stream\n");
+ }
+ break;
case DWC3_DEPEVT_RXTXFIFOEVT:
dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name);
break;
- case DWC3_DEPEVT_STREAMEVT:
- dev_dbg(dwc->dev, "%s Stream Event\n", dep->name);
- break;
case DWC3_DEPEVT_EPCMDCMPLT:
dwc3_ep_cmd_compl(dep, event);
break;