aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/core.h6
-rw-r--r--drivers/usb/dwc3/gadget.c34
2 files changed, 36 insertions, 4 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 502582ce1fc..c6de53c812a 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -329,6 +329,7 @@ struct dwc3_event_buffer {
329 * @interval: the intervall on which the ISOC transfer is started 329 * @interval: the intervall on which the ISOC transfer is started
330 * @name: a human readable name e.g. ep1out-bulk 330 * @name: a human readable name e.g. ep1out-bulk
331 * @direction: true for TX, false for RX 331 * @direction: true for TX, false for RX
332 * @stream_capable: true when streams are enabled
332 */ 333 */
333struct dwc3_ep { 334struct dwc3_ep {
334 struct usb_ep endpoint; 335 struct usb_ep endpoint;
@@ -362,6 +363,7 @@ struct dwc3_ep {
362 char name[20]; 363 char name[20];
363 364
364 unsigned direction:1; 365 unsigned direction:1;
366 unsigned stream_capable:1;
365}; 367};
366 368
367enum dwc3_phy { 369enum dwc3_phy {
@@ -650,6 +652,10 @@ struct dwc3_event_depevt {
650#define DEPEVT_STATUS_IOC (1 << 2) 652#define DEPEVT_STATUS_IOC (1 << 2)
651#define DEPEVT_STATUS_LST (1 << 3) 653#define DEPEVT_STATUS_LST (1 << 3)
652 654
655/* Stream event only */
656#define DEPEVT_STREAMEVT_FOUND 1
657#define DEPEVT_STREAMEVT_NOTFOUND 2
658
653/* Control-only Status */ 659/* Control-only Status */
654#define DEPEVT_STATUS_CONTROL_SETUP 0 660#define DEPEVT_STATUS_CONTROL_SETUP 0
655#define DEPEVT_STATUS_CONTROL_DATA 1 661#define DEPEVT_STATUS_CONTROL_DATA 1
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 524ff91bf39..8d8502373db 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,
264 params.param1.depcfg.xfer_complete_enable = true; 264 params.param1.depcfg.xfer_complete_enable = true;
265 params.param1.depcfg.xfer_not_ready_enable = true; 265 params.param1.depcfg.xfer_not_ready_enable = true;
266 266
267 if (usb_endpoint_xfer_bulk(desc) && dep->endpoint.max_streams) {
268 params.param1.depcfg.stream_capable = true;
269 params.param1.depcfg.stream_event_enable = true;
270 dep->stream_capable = true;
271 }
272
267 if (usb_endpoint_xfer_isoc(desc)) 273 if (usb_endpoint_xfer_isoc(desc))
268 params.param1.depcfg.xfer_in_progress_enable = true; 274 params.param1.depcfg.xfer_in_progress_enable = true;
269 275
@@ -391,15 +397,16 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
391 struct dwc3 *dwc = dep->dwc; 397 struct dwc3 *dwc = dep->dwc;
392 u32 reg; 398 u32 reg;
393 399
394 dep->flags &= ~DWC3_EP_ENABLED;
395 dwc3_remove_requests(dwc, dep); 400 dwc3_remove_requests(dwc, dep);
396 401
397 reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); 402 reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
398 reg &= ~DWC3_DALEPENA_EP(dep->number); 403 reg &= ~DWC3_DALEPENA_EP(dep->number);
399 dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); 404 dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
400 405
406 dep->stream_capable = false;
401 dep->desc = NULL; 407 dep->desc = NULL;
402 dep->type = 0; 408 dep->type = 0;
409 dep->flags = 0;
403 410
404 return 0; 411 return 0;
405} 412}
@@ -633,6 +640,9 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
633 trb.lst = last_one; 640 trb.lst = last_one;
634 } 641 }
635 642
643 if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
644 trb.sid_sofn = req->request.stream_id;
645
636 switch (usb_endpoint_type(dep->desc)) { 646 switch (usb_endpoint_type(dep->desc)) {
637 case USB_ENDPOINT_XFER_CONTROL: 647 case USB_ENDPOINT_XFER_CONTROL:
638 trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP; 648 trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;
@@ -1505,12 +1515,28 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
1505 } 1515 }
1506 1516
1507 break; 1517 break;
1518 case DWC3_DEPEVT_STREAMEVT:
1519 if (!usb_endpoint_xfer_bulk(dep->desc)) {
1520 dev_err(dwc->dev, "Stream event for non-Bulk %s\n",
1521 dep->name);
1522 return;
1523 }
1524
1525 switch (event->status) {
1526 case DEPEVT_STREAMEVT_FOUND:
1527 dev_vdbg(dwc->dev, "Stream %d found and started\n",
1528 event->parameters);
1529
1530 break;
1531 case DEPEVT_STREAMEVT_NOTFOUND:
1532 /* FALLTHROUGH */
1533 default:
1534 dev_dbg(dwc->dev, "Couldn't find suitable stream\n");
1535 }
1536 break;
1508 case DWC3_DEPEVT_RXTXFIFOEVT: 1537 case DWC3_DEPEVT_RXTXFIFOEVT:
1509 dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name); 1538 dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name);
1510 break; 1539 break;
1511 case DWC3_DEPEVT_STREAMEVT:
1512 dev_dbg(dwc->dev, "%s Stream Event\n", dep->name);
1513 break;
1514 case DWC3_DEPEVT_EPCMDCMPLT: 1540 case DWC3_DEPEVT_EPCMDCMPLT:
1515 dwc3_ep_cmd_compl(dep, event); 1541 dwc3_ep_cmd_compl(dep, event);
1516 break; 1542 break;