diff options
author | Vardan Mikayelyan <mvardan@synopsys.com> | 2016-05-25 21:07:12 -0400 |
---|---|---|
committer | Felipe Balbi <felipe.balbi@linux.intel.com> | 2016-06-21 03:49:47 -0400 |
commit | 41cc4cd2716fa6d18a1a09d740ea075adecfa7dd (patch) | |
tree | cfd6eeff6da4755557c88465a8510e6ead0add4f /drivers/usb/dwc2 | |
parent | 326015887b6a1321fd61f7a16816241ad841a03c (diff) |
usb: dwc2: gadget: Add dwc2_gadget_start_next_request function
Replaced repeating code with function call.
Starts next request from ep queue.
If queue is empty and ep is isoc
-In case of OUT-EP unmasks OUTTKNEPDIS.
OUTTKNEPDIS is masked in it's handler, so we need to unmask it here
to be able to do resynchronization.
Tested-by: John Keeping <john@metanate.com>
Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/dwc2')
-rw-r--r-- | drivers/usb/dwc2/gadget.c | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 8139efdf00fb..7db9f9fa40de 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
@@ -1045,6 +1045,42 @@ static struct dwc2_hsotg_req *get_ep_head(struct dwc2_hsotg_ep *hs_ep) | |||
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | /** | 1047 | /** |
1048 | * dwc2_gadget_start_next_request - Starts next request from ep queue | ||
1049 | * @hs_ep: Endpoint structure | ||
1050 | * | ||
1051 | * If queue is empty and EP is ISOC-OUT - unmasks OUTTKNEPDIS which is masked | ||
1052 | * in its handler. Hence we need to unmask it here to be able to do | ||
1053 | * resynchronization. | ||
1054 | */ | ||
1055 | static void dwc2_gadget_start_next_request(struct dwc2_hsotg_ep *hs_ep) | ||
1056 | { | ||
1057 | u32 mask; | ||
1058 | struct dwc2_hsotg *hsotg = hs_ep->parent; | ||
1059 | int dir_in = hs_ep->dir_in; | ||
1060 | struct dwc2_hsotg_req *hs_req; | ||
1061 | u32 epmsk_reg = dir_in ? DIEPMSK : DOEPMSK; | ||
1062 | |||
1063 | if (!list_empty(&hs_ep->queue)) { | ||
1064 | hs_req = get_ep_head(hs_ep); | ||
1065 | dwc2_hsotg_start_req(hsotg, hs_ep, hs_req, false); | ||
1066 | return; | ||
1067 | } | ||
1068 | if (!hs_ep->isochronous) | ||
1069 | return; | ||
1070 | |||
1071 | if (dir_in) { | ||
1072 | dev_dbg(hsotg->dev, "%s: No more ISOC-IN requests\n", | ||
1073 | __func__); | ||
1074 | } else { | ||
1075 | dev_dbg(hsotg->dev, "%s: No more ISOC-OUT requests\n", | ||
1076 | __func__); | ||
1077 | mask = dwc2_readl(hsotg->regs + epmsk_reg); | ||
1078 | mask |= DOEPMSK_OUTTKNEPDISMSK; | ||
1079 | dwc2_writel(mask, hsotg->regs + epmsk_reg); | ||
1080 | } | ||
1081 | } | ||
1082 | |||
1083 | /** | ||
1048 | * dwc2_hsotg_process_req_feature - process request {SET,CLEAR}_FEATURE | 1084 | * dwc2_hsotg_process_req_feature - process request {SET,CLEAR}_FEATURE |
1049 | * @hsotg: The device state | 1085 | * @hsotg: The device state |
1050 | * @ctrl: USB control request | 1086 | * @ctrl: USB control request |
@@ -1054,7 +1090,6 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, | |||
1054 | { | 1090 | { |
1055 | struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0]; | 1091 | struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0]; |
1056 | struct dwc2_hsotg_req *hs_req; | 1092 | struct dwc2_hsotg_req *hs_req; |
1057 | bool restart; | ||
1058 | bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); | 1093 | bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); |
1059 | struct dwc2_hsotg_ep *ep; | 1094 | struct dwc2_hsotg_ep *ep; |
1060 | int ret; | 1095 | int ret; |
@@ -1137,12 +1172,7 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, | |||
1137 | 1172 | ||
1138 | /* If we have pending request, then start it */ | 1173 | /* If we have pending request, then start it */ |
1139 | if (!ep->req) { | 1174 | if (!ep->req) { |
1140 | restart = !list_empty(&ep->queue); | 1175 | dwc2_gadget_start_next_request(ep); |
1141 | if (restart) { | ||
1142 | hs_req = get_ep_head(ep); | ||
1143 | dwc2_hsotg_start_req(hsotg, ep, | ||
1144 | hs_req, false); | ||
1145 | } | ||
1146 | } | 1176 | } |
1147 | } | 1177 | } |
1148 | 1178 | ||
@@ -1383,7 +1413,6 @@ static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg, | |||
1383 | struct dwc2_hsotg_req *hs_req, | 1413 | struct dwc2_hsotg_req *hs_req, |
1384 | int result) | 1414 | int result) |
1385 | { | 1415 | { |
1386 | bool restart; | ||
1387 | 1416 | ||
1388 | if (!hs_req) { | 1417 | if (!hs_req) { |
1389 | dev_dbg(hsotg->dev, "%s: nothing to complete?\n", __func__); | 1418 | dev_dbg(hsotg->dev, "%s: nothing to complete?\n", __func__); |
@@ -1427,11 +1456,7 @@ static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg, | |||
1427 | */ | 1456 | */ |
1428 | 1457 | ||
1429 | if (!hs_ep->req && result >= 0) { | 1458 | if (!hs_ep->req && result >= 0) { |
1430 | restart = !list_empty(&hs_ep->queue); | 1459 | dwc2_gadget_start_next_request(hs_ep); |
1431 | if (restart) { | ||
1432 | hs_req = get_ep_head(hs_ep); | ||
1433 | dwc2_hsotg_start_req(hsotg, hs_ep, hs_req, false); | ||
1434 | } | ||
1435 | } | 1460 | } |
1436 | } | 1461 | } |
1437 | 1462 | ||