diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-07-16 16:16:09 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-07-16 16:16:09 -0400 |
commit | b903bd69e3fa156598def8d6433dfe5352af8da3 (patch) | |
tree | a13380f31bab62acfd667910656525c09511cb8a /drivers/usb/dwc3/gadget.c | |
parent | 84a1caf1453c3d44050bd22db958af4a7f99315c (diff) | |
parent | 1a49e2ac9651df7349867a5cf44e2c83de1046af (diff) |
Merge 3.5-rc7 into usb-next
This resolves the merge issue with the drivers/usb/host/ehci-omap.c
file.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 365 |
1 files changed, 217 insertions, 148 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index ec70df7aba17..58fdfad96b4d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -100,6 +100,23 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) | |||
100 | int retries = 10000; | 100 | int retries = 10000; |
101 | u32 reg; | 101 | u32 reg; |
102 | 102 | ||
103 | /* | ||
104 | * Wait until device controller is ready. Only applies to 1.94a and | ||
105 | * later RTL. | ||
106 | */ | ||
107 | if (dwc->revision >= DWC3_REVISION_194A) { | ||
108 | while (--retries) { | ||
109 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | ||
110 | if (reg & DWC3_DSTS_DCNRD) | ||
111 | udelay(5); | ||
112 | else | ||
113 | break; | ||
114 | } | ||
115 | |||
116 | if (retries <= 0) | ||
117 | return -ETIMEDOUT; | ||
118 | } | ||
119 | |||
103 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 120 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
104 | reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; | 121 | reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; |
105 | 122 | ||
@@ -107,7 +124,15 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) | |||
107 | reg |= DWC3_DCTL_ULSTCHNGREQ(state); | 124 | reg |= DWC3_DCTL_ULSTCHNGREQ(state); |
108 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 125 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); |
109 | 126 | ||
127 | /* | ||
128 | * The following code is racy when called from dwc3_gadget_wakeup, | ||
129 | * and is not needed, at least on newer versions | ||
130 | */ | ||
131 | if (dwc->revision >= DWC3_REVISION_194A) | ||
132 | return 0; | ||
133 | |||
110 | /* wait for a change in DSTS */ | 134 | /* wait for a change in DSTS */ |
135 | retries = 10000; | ||
111 | while (--retries) { | 136 | while (--retries) { |
112 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); | 137 | reg = dwc3_readl(dwc->regs, DWC3_DSTS); |
113 | 138 | ||
@@ -265,8 +290,8 @@ static const char *dwc3_gadget_ep_cmd_string(u8 cmd) | |||
265 | return "Clear Stall"; | 290 | return "Clear Stall"; |
266 | case DWC3_DEPCMD_SETSTALL: | 291 | case DWC3_DEPCMD_SETSTALL: |
267 | return "Set Stall"; | 292 | return "Set Stall"; |
268 | case DWC3_DEPCMD_GETSEQNUMBER: | 293 | case DWC3_DEPCMD_GETEPSTATE: |
269 | return "Get Data Sequence Number"; | 294 | return "Get Endpoint State"; |
270 | case DWC3_DEPCMD_SETTRANSFRESOURCE: | 295 | case DWC3_DEPCMD_SETTRANSFRESOURCE: |
271 | return "Set Endpoint Transfer Resource"; | 296 | return "Set Endpoint Transfer Resource"; |
272 | case DWC3_DEPCMD_SETEPCONFIG: | 297 | case DWC3_DEPCMD_SETEPCONFIG: |
@@ -414,7 +439,7 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
414 | 439 | ||
415 | params.param0 = DWC3_DEPCFG_EP_TYPE(usb_endpoint_type(desc)) | 440 | params.param0 = DWC3_DEPCFG_EP_TYPE(usb_endpoint_type(desc)) |
416 | | DWC3_DEPCFG_MAX_PACKET_SIZE(usb_endpoint_maxp(desc)) | 441 | | DWC3_DEPCFG_MAX_PACKET_SIZE(usb_endpoint_maxp(desc)) |
417 | | DWC3_DEPCFG_BURST_SIZE(dep->endpoint.maxburst); | 442 | | DWC3_DEPCFG_BURST_SIZE(dep->endpoint.maxburst - 1); |
418 | 443 | ||
419 | params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN | 444 | params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN |
420 | | DWC3_DEPCFG_XFER_NOT_READY_EN; | 445 | | DWC3_DEPCFG_XFER_NOT_READY_EN; |
@@ -530,9 +555,37 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) | |||
530 | { | 555 | { |
531 | struct dwc3_request *req; | 556 | struct dwc3_request *req; |
532 | 557 | ||
533 | if (!list_empty(&dep->req_queued)) | 558 | if (!list_empty(&dep->req_queued)) { |
534 | dwc3_stop_active_transfer(dwc, dep->number); | 559 | dwc3_stop_active_transfer(dwc, dep->number); |
535 | 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 | while (!list_empty(&dep->req_queued)) { | ||
583 | req = next_request(&dep->req_queued); | ||
584 | |||
585 | dwc3_gadget_giveback(dep, req, -ESHUTDOWN); | ||
586 | } | ||
587 | } | ||
588 | |||
536 | while (!list_empty(&dep->request_list)) { | 589 | while (!list_empty(&dep->request_list)) { |
537 | req = next_request(&dep->request_list); | 590 | req = next_request(&dep->request_list); |
538 | 591 | ||
@@ -741,8 +794,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, | |||
741 | case USB_ENDPOINT_XFER_ISOC: | 794 | case USB_ENDPOINT_XFER_ISOC: |
742 | trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; | 795 | trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; |
743 | 796 | ||
744 | /* IOC every DWC3_TRB_NUM / 4 so we can refill */ | 797 | if (!req->request.no_interrupt) |
745 | if (!(cur_slot % (DWC3_TRB_NUM / 4))) | ||
746 | trb->ctrl |= DWC3_TRB_CTRL_IOC; | 798 | trb->ctrl |= DWC3_TRB_CTRL_IOC; |
747 | break; | 799 | break; |
748 | 800 | ||
@@ -958,14 +1010,42 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, | |||
958 | dep->flags |= DWC3_EP_BUSY; | 1010 | dep->flags |= DWC3_EP_BUSY; |
959 | 1011 | ||
960 | if (start_new) { | 1012 | if (start_new) { |
961 | dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc, | 1013 | dep->resource_index = dwc3_gadget_ep_get_transfer_index(dwc, |
962 | dep->number); | 1014 | dep->number); |
963 | WARN_ON_ONCE(!dep->res_trans_idx); | 1015 | WARN_ON_ONCE(!dep->resource_index); |
964 | } | 1016 | } |
965 | 1017 | ||
966 | return 0; | 1018 | return 0; |
967 | } | 1019 | } |
968 | 1020 | ||
1021 | static void __dwc3_gadget_start_isoc(struct dwc3 *dwc, | ||
1022 | struct dwc3_ep *dep, u32 cur_uf) | ||
1023 | { | ||
1024 | u32 uf; | ||
1025 | |||
1026 | if (list_empty(&dep->request_list)) { | ||
1027 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", | ||
1028 | dep->name); | ||
1029 | return; | ||
1030 | } | ||
1031 | |||
1032 | /* 4 micro frames in the future */ | ||
1033 | uf = cur_uf + dep->interval * 4; | ||
1034 | |||
1035 | __dwc3_gadget_kick_transfer(dep, uf, 1); | ||
1036 | } | ||
1037 | |||
1038 | static void dwc3_gadget_start_isoc(struct dwc3 *dwc, | ||
1039 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event) | ||
1040 | { | ||
1041 | u32 cur_uf, mask; | ||
1042 | |||
1043 | mask = ~(dep->interval - 1); | ||
1044 | cur_uf = event->parameters & mask; | ||
1045 | |||
1046 | __dwc3_gadget_start_isoc(dwc, dep, cur_uf); | ||
1047 | } | ||
1048 | |||
969 | static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | 1049 | static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) |
970 | { | 1050 | { |
971 | struct dwc3 *dwc = dep->dwc; | 1051 | struct dwc3 *dwc = dep->dwc; |
@@ -995,11 +1075,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
995 | 1075 | ||
996 | list_add_tail(&req->list, &dep->request_list); | 1076 | list_add_tail(&req->list, &dep->request_list); |
997 | 1077 | ||
998 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && (dep->flags & DWC3_EP_BUSY)) | ||
999 | dep->flags |= DWC3_EP_PENDING_REQUEST; | ||
1000 | |||
1001 | /* | 1078 | /* |
1002 | * There are two special cases: | 1079 | * There are a few special cases: |
1003 | * | 1080 | * |
1004 | * 1. XferNotReady with empty list of requests. We need to kick the | 1081 | * 1. XferNotReady with empty list of requests. We need to kick the |
1005 | * transfer here in that situation, otherwise we will be NAKing | 1082 | * transfer here in that situation, otherwise we will be NAKing |
@@ -1008,31 +1085,46 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1008 | * able to receive the data until the next request is queued. | 1085 | * able to receive the data until the next request is queued. |
1009 | * The following code is handling exactly that. | 1086 | * The following code is handling exactly that. |
1010 | * | 1087 | * |
1011 | * 2. XferInProgress on Isoc EP with an active transfer. We need to | ||
1012 | * kick the transfer here after queuing a request, otherwise the | ||
1013 | * core may not see the modified TRB(s). | ||
1014 | */ | 1088 | */ |
1015 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | 1089 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { |
1016 | int ret; | 1090 | int ret; |
1017 | int start_trans = 1; | ||
1018 | u8 trans_idx = dep->res_trans_idx; | ||
1019 | 1091 | ||
1020 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && | 1092 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); |
1021 | (dep->flags & DWC3_EP_BUSY)) { | 1093 | if (ret && ret != -EBUSY) { |
1022 | start_trans = 0; | 1094 | struct dwc3 *dwc = dep->dwc; |
1023 | WARN_ON_ONCE(!trans_idx); | 1095 | |
1024 | } else { | 1096 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", |
1025 | trans_idx = 0; | 1097 | dep->name); |
1026 | } | 1098 | } |
1099 | } | ||
1027 | 1100 | ||
1028 | ret = __dwc3_gadget_kick_transfer(dep, trans_idx, start_trans); | 1101 | /* |
1102 | * 2. XferInProgress on Isoc EP with an active transfer. We need to | ||
1103 | * kick the transfer here after queuing a request, otherwise the | ||
1104 | * core may not see the modified TRB(s). | ||
1105 | */ | ||
1106 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && | ||
1107 | (dep->flags & DWC3_EP_BUSY)) { | ||
1108 | WARN_ON_ONCE(!dep->resource_index); | ||
1109 | ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index, | ||
1110 | false); | ||
1029 | if (ret && ret != -EBUSY) { | 1111 | if (ret && ret != -EBUSY) { |
1030 | struct dwc3 *dwc = dep->dwc; | 1112 | struct dwc3 *dwc = dep->dwc; |
1031 | 1113 | ||
1032 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", | 1114 | dev_dbg(dwc->dev, "%s: failed to kick transfers\n", |
1033 | dep->name); | 1115 | dep->name); |
1034 | } | 1116 | } |
1035 | }; | 1117 | } |
1118 | |||
1119 | /* | ||
1120 | * 3. Missed ISOC Handling. We need to start isoc transfer on the saved | ||
1121 | * uframe number. | ||
1122 | */ | ||
1123 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && | ||
1124 | (dep->flags & DWC3_EP_MISSED_ISOC)) { | ||
1125 | __dwc3_gadget_start_isoc(dwc, dep, dep->current_uf); | ||
1126 | dep->flags &= ~DWC3_EP_MISSED_ISOC; | ||
1127 | } | ||
1036 | 1128 | ||
1037 | return 0; | 1129 | return 0; |
1038 | } | 1130 | } |
@@ -1118,15 +1210,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value) | |||
1118 | memset(¶ms, 0x00, sizeof(params)); | 1210 | memset(¶ms, 0x00, sizeof(params)); |
1119 | 1211 | ||
1120 | if (value) { | 1212 | if (value) { |
1121 | if (dep->number == 0 || dep->number == 1) { | ||
1122 | /* | ||
1123 | * Whenever EP0 is stalled, we will restart | ||
1124 | * the state machine, thus moving back to | ||
1125 | * Setup Phase | ||
1126 | */ | ||
1127 | dwc->ep0state = EP0_SETUP_PHASE; | ||
1128 | } | ||
1129 | |||
1130 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | 1213 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, |
1131 | DWC3_DEPCMD_SETSTALL, ¶ms); | 1214 | DWC3_DEPCMD_SETSTALL, ¶ms); |
1132 | if (ret) | 1215 | if (ret) |
@@ -1186,7 +1269,10 @@ static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep) | |||
1186 | dep->flags |= DWC3_EP_WEDGE; | 1269 | dep->flags |= DWC3_EP_WEDGE; |
1187 | spin_unlock_irqrestore(&dwc->lock, flags); | 1270 | spin_unlock_irqrestore(&dwc->lock, flags); |
1188 | 1271 | ||
1189 | return dwc3_gadget_ep_set_halt(ep, 1); | 1272 | if (dep->number == 0 || dep->number == 1) |
1273 | return dwc3_gadget_ep0_set_halt(ep, 1); | ||
1274 | else | ||
1275 | return dwc3_gadget_ep_set_halt(ep, 1); | ||
1190 | } | 1276 | } |
1191 | 1277 | ||
1192 | /* -------------------------------------------------------------------------- */ | 1278 | /* -------------------------------------------------------------------------- */ |
@@ -1204,7 +1290,7 @@ static const struct usb_ep_ops dwc3_gadget_ep0_ops = { | |||
1204 | .free_request = dwc3_gadget_ep_free_request, | 1290 | .free_request = dwc3_gadget_ep_free_request, |
1205 | .queue = dwc3_gadget_ep0_queue, | 1291 | .queue = dwc3_gadget_ep0_queue, |
1206 | .dequeue = dwc3_gadget_ep_dequeue, | 1292 | .dequeue = dwc3_gadget_ep_dequeue, |
1207 | .set_halt = dwc3_gadget_ep_set_halt, | 1293 | .set_halt = dwc3_gadget_ep0_set_halt, |
1208 | .set_wedge = dwc3_gadget_ep_set_wedge, | 1294 | .set_wedge = dwc3_gadget_ep_set_wedge, |
1209 | }; | 1295 | }; |
1210 | 1296 | ||
@@ -1280,9 +1366,13 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g) | |||
1280 | goto out; | 1366 | goto out; |
1281 | } | 1367 | } |
1282 | 1368 | ||
1283 | /* write zeroes to Link Change Request */ | 1369 | /* Recent versions do this automatically */ |
1284 | reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; | 1370 | if (dwc->revision < DWC3_REVISION_194A) { |
1285 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 1371 | /* write zeroes to Link Change Request */ |
1372 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
1373 | reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; | ||
1374 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
1375 | } | ||
1286 | 1376 | ||
1287 | /* poll until Link State changes to ON */ | 1377 | /* poll until Link State changes to ON */ |
1288 | timeout = jiffies + msecs_to_jiffies(100); | 1378 | timeout = jiffies + msecs_to_jiffies(100); |
@@ -1319,16 +1409,21 @@ static int dwc3_gadget_set_selfpowered(struct usb_gadget *g, | |||
1319 | return 0; | 1409 | return 0; |
1320 | } | 1410 | } |
1321 | 1411 | ||
1322 | static void dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) | 1412 | static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) |
1323 | { | 1413 | { |
1324 | u32 reg; | 1414 | u32 reg; |
1325 | u32 timeout = 500; | 1415 | u32 timeout = 500; |
1326 | 1416 | ||
1327 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 1417 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
1328 | if (is_on) { | 1418 | if (is_on) { |
1329 | reg &= ~DWC3_DCTL_TRGTULST_MASK; | 1419 | if (dwc->revision <= DWC3_REVISION_187A) { |
1330 | reg |= (DWC3_DCTL_RUN_STOP | 1420 | reg &= ~DWC3_DCTL_TRGTULST_MASK; |
1331 | | DWC3_DCTL_TRGTULST_RX_DET); | 1421 | reg |= DWC3_DCTL_TRGTULST_RX_DET; |
1422 | } | ||
1423 | |||
1424 | if (dwc->revision >= DWC3_REVISION_194A) | ||
1425 | reg &= ~DWC3_DCTL_KEEP_CONNECT; | ||
1426 | reg |= DWC3_DCTL_RUN_STOP; | ||
1332 | } else { | 1427 | } else { |
1333 | reg &= ~DWC3_DCTL_RUN_STOP; | 1428 | reg &= ~DWC3_DCTL_RUN_STOP; |
1334 | } | 1429 | } |
@@ -1346,7 +1441,7 @@ static void dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) | |||
1346 | } | 1441 | } |
1347 | timeout--; | 1442 | timeout--; |
1348 | if (!timeout) | 1443 | if (!timeout) |
1349 | break; | 1444 | return -ETIMEDOUT; |
1350 | udelay(1); | 1445 | udelay(1); |
1351 | } while (1); | 1446 | } while (1); |
1352 | 1447 | ||
@@ -1354,20 +1449,23 @@ static void dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) | |||
1354 | dwc->gadget_driver | 1449 | dwc->gadget_driver |
1355 | ? dwc->gadget_driver->function : "no-function", | 1450 | ? dwc->gadget_driver->function : "no-function", |
1356 | is_on ? "connect" : "disconnect"); | 1451 | is_on ? "connect" : "disconnect"); |
1452 | |||
1453 | return 0; | ||
1357 | } | 1454 | } |
1358 | 1455 | ||
1359 | static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) | 1456 | static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) |
1360 | { | 1457 | { |
1361 | struct dwc3 *dwc = gadget_to_dwc(g); | 1458 | struct dwc3 *dwc = gadget_to_dwc(g); |
1362 | unsigned long flags; | 1459 | unsigned long flags; |
1460 | int ret; | ||
1363 | 1461 | ||
1364 | is_on = !!is_on; | 1462 | is_on = !!is_on; |
1365 | 1463 | ||
1366 | spin_lock_irqsave(&dwc->lock, flags); | 1464 | spin_lock_irqsave(&dwc->lock, flags); |
1367 | dwc3_gadget_run_stop(dwc, is_on); | 1465 | ret = dwc3_gadget_run_stop(dwc, is_on); |
1368 | spin_unlock_irqrestore(&dwc->lock, flags); | 1466 | spin_unlock_irqrestore(&dwc->lock, flags); |
1369 | 1467 | ||
1370 | return 0; | 1468 | return ret; |
1371 | } | 1469 | } |
1372 | 1470 | ||
1373 | static int dwc3_gadget_start(struct usb_gadget *g, | 1471 | static int dwc3_gadget_start(struct usb_gadget *g, |
@@ -1468,6 +1566,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g, | |||
1468 | 1566 | ||
1469 | return 0; | 1567 | return 0; |
1470 | } | 1568 | } |
1569 | |||
1471 | static const struct usb_gadget_ops dwc3_gadget_ops = { | 1570 | static const struct usb_gadget_ops dwc3_gadget_ops = { |
1472 | .get_frame = dwc3_gadget_get_frame, | 1571 | .get_frame = dwc3_gadget_get_frame, |
1473 | .wakeup = dwc3_gadget_wakeup, | 1572 | .wakeup = dwc3_gadget_wakeup, |
@@ -1558,6 +1657,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
1558 | struct dwc3_trb *trb; | 1657 | struct dwc3_trb *trb; |
1559 | unsigned int count; | 1658 | unsigned int count; |
1560 | unsigned int s_pkt = 0; | 1659 | unsigned int s_pkt = 0; |
1660 | unsigned int trb_status; | ||
1561 | 1661 | ||
1562 | do { | 1662 | do { |
1563 | req = next_request(&dep->req_queued); | 1663 | req = next_request(&dep->req_queued); |
@@ -1583,9 +1683,18 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
1583 | 1683 | ||
1584 | if (dep->direction) { | 1684 | if (dep->direction) { |
1585 | if (count) { | 1685 | if (count) { |
1586 | dev_err(dwc->dev, "incomplete IN transfer %s\n", | 1686 | trb_status = DWC3_TRB_SIZE_TRBSTS(trb->size); |
1587 | dep->name); | 1687 | if (trb_status == DWC3_TRBSTS_MISSED_ISOC) { |
1588 | status = -ECONNRESET; | 1688 | dev_dbg(dwc->dev, "incomplete IN transfer %s\n", |
1689 | dep->name); | ||
1690 | dep->current_uf = event->parameters & | ||
1691 | ~(dep->interval - 1); | ||
1692 | dep->flags |= DWC3_EP_MISSED_ISOC; | ||
1693 | } else { | ||
1694 | dev_err(dwc->dev, "incomplete IN transfer %s\n", | ||
1695 | dep->name); | ||
1696 | status = -ECONNRESET; | ||
1697 | } | ||
1589 | } | 1698 | } |
1590 | } else { | 1699 | } else { |
1591 | if (count && (event->status & DEPEVT_STATUS_SHORT)) | 1700 | if (count && (event->status & DEPEVT_STATUS_SHORT)) |
@@ -1604,7 +1713,8 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, | |||
1604 | if (s_pkt) | 1713 | if (s_pkt) |
1605 | break; | 1714 | break; |
1606 | if ((event->status & DEPEVT_STATUS_LST) && | 1715 | if ((event->status & DEPEVT_STATUS_LST) && |
1607 | (trb->ctrl & DWC3_TRB_CTRL_LST)) | 1716 | (trb->ctrl & (DWC3_TRB_CTRL_LST | |
1717 | DWC3_TRB_CTRL_HWO))) | ||
1608 | break; | 1718 | break; |
1609 | if ((event->status & DEPEVT_STATUS_IOC) && | 1719 | if ((event->status & DEPEVT_STATUS_IOC) && |
1610 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) | 1720 | (trb->ctrl & DWC3_TRB_CTRL_IOC)) |
@@ -1657,65 +1767,6 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, | |||
1657 | } | 1767 | } |
1658 | } | 1768 | } |
1659 | 1769 | ||
1660 | static void dwc3_gadget_start_isoc(struct dwc3 *dwc, | ||
1661 | struct dwc3_ep *dep, const struct dwc3_event_depevt *event) | ||
1662 | { | ||
1663 | u32 uf, mask; | ||
1664 | |||
1665 | if (list_empty(&dep->request_list)) { | ||
1666 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", | ||
1667 | dep->name); | ||
1668 | return; | ||
1669 | } | ||
1670 | |||
1671 | mask = ~(dep->interval - 1); | ||
1672 | uf = event->parameters & mask; | ||
1673 | /* 4 micro frames in the future */ | ||
1674 | uf += dep->interval * 4; | ||
1675 | |||
1676 | __dwc3_gadget_kick_transfer(dep, uf, 1); | ||
1677 | } | ||
1678 | |||
1679 | static void dwc3_process_ep_cmd_complete(struct dwc3_ep *dep, | ||
1680 | const struct dwc3_event_depevt *event) | ||
1681 | { | ||
1682 | struct dwc3 *dwc = dep->dwc; | ||
1683 | struct dwc3_event_depevt mod_ev = *event; | ||
1684 | |||
1685 | /* | ||
1686 | * We were asked to remove one request. It is possible that this | ||
1687 | * request and a few others were started together and have the same | ||
1688 | * transfer index. Since we stopped the complete endpoint we don't | ||
1689 | * know how many requests were already completed (and not yet) | ||
1690 | * reported and how could be done (later). We purge them all until | ||
1691 | * the end of the list. | ||
1692 | */ | ||
1693 | mod_ev.status = DEPEVT_STATUS_LST; | ||
1694 | dwc3_cleanup_done_reqs(dwc, dep, &mod_ev, -ESHUTDOWN); | ||
1695 | dep->flags &= ~DWC3_EP_BUSY; | ||
1696 | /* pending requests are ignored and are queued on XferNotReady */ | ||
1697 | } | ||
1698 | |||
1699 | static void dwc3_ep_cmd_compl(struct dwc3_ep *dep, | ||
1700 | const struct dwc3_event_depevt *event) | ||
1701 | { | ||
1702 | u32 param = event->parameters; | ||
1703 | u32 cmd_type = (param >> 8) & ((1 << 5) - 1); | ||
1704 | |||
1705 | switch (cmd_type) { | ||
1706 | case DWC3_DEPCMD_ENDTRANSFER: | ||
1707 | dwc3_process_ep_cmd_complete(dep, event); | ||
1708 | break; | ||
1709 | case DWC3_DEPCMD_STARTTRANSFER: | ||
1710 | dep->res_trans_idx = param & 0x7f; | ||
1711 | break; | ||
1712 | default: | ||
1713 | printk(KERN_ERR "%s() unknown /unexpected type: %d\n", | ||
1714 | __func__, cmd_type); | ||
1715 | break; | ||
1716 | }; | ||
1717 | } | ||
1718 | |||
1719 | static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | 1770 | static void dwc3_endpoint_interrupt(struct dwc3 *dwc, |
1720 | const struct dwc3_event_depevt *event) | 1771 | const struct dwc3_event_depevt *event) |
1721 | { | 1772 | { |
@@ -1724,6 +1775,9 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
1724 | 1775 | ||
1725 | dep = dwc->eps[epnum]; | 1776 | dep = dwc->eps[epnum]; |
1726 | 1777 | ||
1778 | if (!(dep->flags & DWC3_EP_ENABLED)) | ||
1779 | return; | ||
1780 | |||
1727 | dev_vdbg(dwc->dev, "%s: %s\n", dep->name, | 1781 | dev_vdbg(dwc->dev, "%s: %s\n", dep->name, |
1728 | dwc3_ep_event_string(event->endpoint_event)); | 1782 | dwc3_ep_event_string(event->endpoint_event)); |
1729 | 1783 | ||
@@ -1734,7 +1788,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
1734 | 1788 | ||
1735 | switch (event->endpoint_event) { | 1789 | switch (event->endpoint_event) { |
1736 | case DWC3_DEPEVT_XFERCOMPLETE: | 1790 | case DWC3_DEPEVT_XFERCOMPLETE: |
1737 | dep->res_trans_idx = 0; | 1791 | dep->resource_index = 0; |
1738 | 1792 | ||
1739 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | 1793 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { |
1740 | dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n", | 1794 | dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n", |
@@ -1797,7 +1851,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, | |||
1797 | dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name); | 1851 | dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name); |
1798 | break; | 1852 | break; |
1799 | case DWC3_DEPEVT_EPCMDCMPLT: | 1853 | case DWC3_DEPEVT_EPCMDCMPLT: |
1800 | dwc3_ep_cmd_compl(dep, event); | 1854 | dev_vdbg(dwc->dev, "Endpoint Command Complete\n"); |
1801 | break; | 1855 | break; |
1802 | } | 1856 | } |
1803 | } | 1857 | } |
@@ -1820,16 +1874,16 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) | |||
1820 | 1874 | ||
1821 | dep = dwc->eps[epnum]; | 1875 | dep = dwc->eps[epnum]; |
1822 | 1876 | ||
1823 | WARN_ON(!dep->res_trans_idx); | 1877 | if (!dep->resource_index) |
1824 | if (dep->res_trans_idx) { | 1878 | return; |
1825 | cmd = DWC3_DEPCMD_ENDTRANSFER; | 1879 | |
1826 | cmd |= DWC3_DEPCMD_HIPRI_FORCERM | DWC3_DEPCMD_CMDIOC; | 1880 | cmd = DWC3_DEPCMD_ENDTRANSFER; |
1827 | cmd |= DWC3_DEPCMD_PARAM(dep->res_trans_idx); | 1881 | cmd |= DWC3_DEPCMD_HIPRI_FORCERM | DWC3_DEPCMD_CMDIOC; |
1828 | memset(¶ms, 0, sizeof(params)); | 1882 | cmd |= DWC3_DEPCMD_PARAM(dep->resource_index); |
1829 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); | 1883 | memset(¶ms, 0, sizeof(params)); |
1830 | WARN_ON_ONCE(ret); | 1884 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); |
1831 | dep->res_trans_idx = 0; | 1885 | WARN_ON_ONCE(ret); |
1832 | } | 1886 | dep->resource_index = 0; |
1833 | } | 1887 | } |
1834 | 1888 | ||
1835 | static void dwc3_stop_active_transfers(struct dwc3 *dwc) | 1889 | static void dwc3_stop_active_transfers(struct dwc3 *dwc) |
@@ -1872,11 +1926,9 @@ static void dwc3_clear_stall_all_ep(struct dwc3 *dwc) | |||
1872 | 1926 | ||
1873 | static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) | 1927 | static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) |
1874 | { | 1928 | { |
1929 | int reg; | ||
1930 | |||
1875 | dev_vdbg(dwc->dev, "%s\n", __func__); | 1931 | dev_vdbg(dwc->dev, "%s\n", __func__); |
1876 | #if 0 | ||
1877 | XXX | ||
1878 | U1/U2 is powersave optimization. Skip it for now. Anyway we need to | ||
1879 | enable it before we can disable it. | ||
1880 | 1932 | ||
1881 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 1933 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
1882 | reg &= ~DWC3_DCTL_INITU1ENA; | 1934 | reg &= ~DWC3_DCTL_INITU1ENA; |
@@ -1884,9 +1936,7 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) | |||
1884 | 1936 | ||
1885 | reg &= ~DWC3_DCTL_INITU2ENA; | 1937 | reg &= ~DWC3_DCTL_INITU2ENA; |
1886 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 1938 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); |
1887 | #endif | ||
1888 | 1939 | ||
1889 | dwc3_stop_active_transfers(dwc); | ||
1890 | dwc3_disconnect_gadget(dwc); | 1940 | dwc3_disconnect_gadget(dwc); |
1891 | dwc->start_config_issued = false; | 1941 | dwc->start_config_issued = false; |
1892 | 1942 | ||
@@ -1894,30 +1944,30 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) | |||
1894 | dwc->setup_packet_pending = false; | 1944 | dwc->setup_packet_pending = false; |
1895 | } | 1945 | } |
1896 | 1946 | ||
1897 | static void dwc3_gadget_usb3_phy_power(struct dwc3 *dwc, int on) | 1947 | static void dwc3_gadget_usb3_phy_suspend(struct dwc3 *dwc, int suspend) |
1898 | { | 1948 | { |
1899 | u32 reg; | 1949 | u32 reg; |
1900 | 1950 | ||
1901 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); | 1951 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); |
1902 | 1952 | ||
1903 | if (on) | 1953 | if (suspend) |
1904 | reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; | ||
1905 | else | ||
1906 | reg |= DWC3_GUSB3PIPECTL_SUSPHY; | 1954 | reg |= DWC3_GUSB3PIPECTL_SUSPHY; |
1955 | else | ||
1956 | reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; | ||
1907 | 1957 | ||
1908 | dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); | 1958 | dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); |
1909 | } | 1959 | } |
1910 | 1960 | ||
1911 | static void dwc3_gadget_usb2_phy_power(struct dwc3 *dwc, int on) | 1961 | static void dwc3_gadget_usb2_phy_suspend(struct dwc3 *dwc, int suspend) |
1912 | { | 1962 | { |
1913 | u32 reg; | 1963 | u32 reg; |
1914 | 1964 | ||
1915 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | 1965 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); |
1916 | 1966 | ||
1917 | if (on) | 1967 | if (suspend) |
1918 | reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; | ||
1919 | else | ||
1920 | reg |= DWC3_GUSB2PHYCFG_SUSPHY; | 1968 | reg |= DWC3_GUSB2PHYCFG_SUSPHY; |
1969 | else | ||
1970 | reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; | ||
1921 | 1971 | ||
1922 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | 1972 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); |
1923 | } | 1973 | } |
@@ -1962,16 +2012,18 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) | |||
1962 | /* after reset -> Default State */ | 2012 | /* after reset -> Default State */ |
1963 | dwc->dev_state = DWC3_DEFAULT_STATE; | 2013 | dwc->dev_state = DWC3_DEFAULT_STATE; |
1964 | 2014 | ||
1965 | /* Enable PHYs */ | 2015 | /* Recent versions support automatic phy suspend and don't need this */ |
1966 | dwc3_gadget_usb2_phy_power(dwc, true); | 2016 | if (dwc->revision < DWC3_REVISION_194A) { |
1967 | dwc3_gadget_usb3_phy_power(dwc, true); | 2017 | /* Resume PHYs */ |
2018 | dwc3_gadget_usb2_phy_suspend(dwc, false); | ||
2019 | dwc3_gadget_usb3_phy_suspend(dwc, false); | ||
2020 | } | ||
1968 | 2021 | ||
1969 | if (dwc->gadget.speed != USB_SPEED_UNKNOWN) | 2022 | if (dwc->gadget.speed != USB_SPEED_UNKNOWN) |
1970 | dwc3_disconnect_gadget(dwc); | 2023 | dwc3_disconnect_gadget(dwc); |
1971 | 2024 | ||
1972 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 2025 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
1973 | reg &= ~DWC3_DCTL_TSTCTRL_MASK; | 2026 | reg &= ~DWC3_DCTL_TSTCTRL_MASK; |
1974 | reg &= ~(DWC3_DCTL_INITU1ENA | DWC3_DCTL_INITU2ENA); | ||
1975 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 2027 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); |
1976 | dwc->test_mode = false; | 2028 | dwc->test_mode = false; |
1977 | 2029 | ||
@@ -2010,16 +2062,16 @@ static void dwc3_update_ram_clk_sel(struct dwc3 *dwc, u32 speed) | |||
2010 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); | 2062 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
2011 | } | 2063 | } |
2012 | 2064 | ||
2013 | static void dwc3_gadget_disable_phy(struct dwc3 *dwc, u8 speed) | 2065 | static void dwc3_gadget_phy_suspend(struct dwc3 *dwc, u8 speed) |
2014 | { | 2066 | { |
2015 | switch (speed) { | 2067 | switch (speed) { |
2016 | case USB_SPEED_SUPER: | 2068 | case USB_SPEED_SUPER: |
2017 | dwc3_gadget_usb2_phy_power(dwc, false); | 2069 | dwc3_gadget_usb2_phy_suspend(dwc, true); |
2018 | break; | 2070 | break; |
2019 | case USB_SPEED_HIGH: | 2071 | case USB_SPEED_HIGH: |
2020 | case USB_SPEED_FULL: | 2072 | case USB_SPEED_FULL: |
2021 | case USB_SPEED_LOW: | 2073 | case USB_SPEED_LOW: |
2022 | dwc3_gadget_usb3_phy_power(dwc, false); | 2074 | dwc3_gadget_usb3_phy_suspend(dwc, true); |
2023 | break; | 2075 | break; |
2024 | } | 2076 | } |
2025 | } | 2077 | } |
@@ -2082,8 +2134,11 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) | |||
2082 | break; | 2134 | break; |
2083 | } | 2135 | } |
2084 | 2136 | ||
2085 | /* Disable unneded PHY */ | 2137 | /* Recent versions support automatic phy suspend and don't need this */ |
2086 | dwc3_gadget_disable_phy(dwc, dwc->gadget.speed); | 2138 | if (dwc->revision < DWC3_REVISION_194A) { |
2139 | /* Suspend unneeded PHY */ | ||
2140 | dwc3_gadget_phy_suspend(dwc, dwc->gadget.speed); | ||
2141 | } | ||
2087 | 2142 | ||
2088 | dep = dwc->eps[0]; | 2143 | dep = dwc->eps[0]; |
2089 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL); | 2144 | ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL); |
@@ -2373,10 +2428,6 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc) | |||
2373 | reg |= DWC3_DCFG_LPM_CAP; | 2428 | reg |= DWC3_DCFG_LPM_CAP; |
2374 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); | 2429 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); |
2375 | 2430 | ||
2376 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
2377 | reg |= DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA; | ||
2378 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
2379 | |||
2380 | /* Enable all but Start and End of Frame IRQs */ | 2431 | /* Enable all but Start and End of Frame IRQs */ |
2381 | reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN | | 2432 | reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN | |
2382 | DWC3_DEVTEN_EVNTOVERFLOWEN | | 2433 | DWC3_DEVTEN_EVNTOVERFLOWEN | |
@@ -2389,6 +2440,24 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc) | |||
2389 | DWC3_DEVTEN_DISCONNEVTEN); | 2440 | DWC3_DEVTEN_DISCONNEVTEN); |
2390 | dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); | 2441 | dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); |
2391 | 2442 | ||
2443 | /* Enable USB2 LPM and automatic phy suspend only on recent versions */ | ||
2444 | if (dwc->revision >= DWC3_REVISION_194A) { | ||
2445 | reg = dwc3_readl(dwc->regs, DWC3_DCFG); | ||
2446 | reg |= DWC3_DCFG_LPM_CAP; | ||
2447 | dwc3_writel(dwc->regs, DWC3_DCFG, reg); | ||
2448 | |||
2449 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | ||
2450 | reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN); | ||
2451 | |||
2452 | /* TODO: This should be configurable */ | ||
2453 | reg |= DWC3_DCTL_HIRD_THRES(28); | ||
2454 | |||
2455 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | ||
2456 | |||
2457 | dwc3_gadget_usb2_phy_suspend(dwc, false); | ||
2458 | dwc3_gadget_usb3_phy_suspend(dwc, false); | ||
2459 | } | ||
2460 | |||
2392 | ret = device_register(&dwc->gadget.dev); | 2461 | ret = device_register(&dwc->gadget.dev); |
2393 | if (ret) { | 2462 | if (ret) { |
2394 | dev_err(dwc->dev, "failed to register gadget device\n"); | 2463 | dev_err(dwc->dev, "failed to register gadget device\n"); |