diff options
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 3818b26bfc05..546ea5431b8c 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -525,12 +525,11 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, | |||
525 | if (!usb_endpoint_xfer_isoc(desc)) | 525 | if (!usb_endpoint_xfer_isoc(desc)) |
526 | return 0; | 526 | return 0; |
527 | 527 | ||
528 | memset(&trb_link, 0, sizeof(trb_link)); | ||
529 | |||
530 | /* Link TRB for ISOC. The HWO bit is never reset */ | 528 | /* Link TRB for ISOC. The HWO bit is never reset */ |
531 | trb_st_hw = &dep->trb_pool[0]; | 529 | trb_st_hw = &dep->trb_pool[0]; |
532 | 530 | ||
533 | trb_link = &dep->trb_pool[DWC3_TRB_NUM - 1]; | 531 | trb_link = &dep->trb_pool[DWC3_TRB_NUM - 1]; |
532 | memset(trb_link, 0, sizeof(*trb_link)); | ||
534 | 533 | ||
535 | trb_link->bpl = lower_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw)); | 534 | trb_link->bpl = lower_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw)); |
536 | trb_link->bph = upper_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw)); | 535 | trb_link->bph = upper_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw)); |
@@ -581,7 +580,7 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) | |||
581 | 580 | ||
582 | /* make sure HW endpoint isn't stalled */ | 581 | /* make sure HW endpoint isn't stalled */ |
583 | if (dep->flags & DWC3_EP_STALL) | 582 | if (dep->flags & DWC3_EP_STALL) |
584 | __dwc3_gadget_ep_set_halt(dep, 0); | 583 | __dwc3_gadget_ep_set_halt(dep, 0, false); |
585 | 584 | ||
586 | reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); | 585 | reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); |
587 | reg &= ~DWC3_DALEPENA_EP(dep->number); | 586 | reg &= ~DWC3_DALEPENA_EP(dep->number); |
@@ -1202,15 +1201,28 @@ out0: | |||
1202 | return ret; | 1201 | return ret; |
1203 | } | 1202 | } |
1204 | 1203 | ||
1205 | int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value) | 1204 | int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol) |
1206 | { | 1205 | { |
1207 | struct dwc3_gadget_ep_cmd_params params; | 1206 | struct dwc3_gadget_ep_cmd_params params; |
1208 | struct dwc3 *dwc = dep->dwc; | 1207 | struct dwc3 *dwc = dep->dwc; |
1209 | int ret; | 1208 | int ret; |
1210 | 1209 | ||
1210 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | ||
1211 | dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name); | ||
1212 | return -EINVAL; | ||
1213 | } | ||
1214 | |||
1211 | memset(¶ms, 0x00, sizeof(params)); | 1215 | memset(¶ms, 0x00, sizeof(params)); |
1212 | 1216 | ||
1213 | if (value) { | 1217 | if (value) { |
1218 | if (!protocol && ((dep->direction && dep->flags & DWC3_EP_BUSY) || | ||
1219 | (!list_empty(&dep->req_queued) || | ||
1220 | !list_empty(&dep->request_list)))) { | ||
1221 | dev_dbg(dwc->dev, "%s: pending request, cannot halt\n", | ||
1222 | dep->name); | ||
1223 | return -EAGAIN; | ||
1224 | } | ||
1225 | |||
1214 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | 1226 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, |
1215 | DWC3_DEPCMD_SETSTALL, ¶ms); | 1227 | DWC3_DEPCMD_SETSTALL, ¶ms); |
1216 | if (ret) | 1228 | if (ret) |
@@ -1241,15 +1253,7 @@ static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value) | |||
1241 | int ret; | 1253 | int ret; |
1242 | 1254 | ||
1243 | spin_lock_irqsave(&dwc->lock, flags); | 1255 | spin_lock_irqsave(&dwc->lock, flags); |
1244 | 1256 | ret = __dwc3_gadget_ep_set_halt(dep, value, false); | |
1245 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | ||
1246 | dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name); | ||
1247 | ret = -EINVAL; | ||
1248 | goto out; | ||
1249 | } | ||
1250 | |||
1251 | ret = __dwc3_gadget_ep_set_halt(dep, value); | ||
1252 | out: | ||
1253 | spin_unlock_irqrestore(&dwc->lock, flags); | 1257 | spin_unlock_irqrestore(&dwc->lock, flags); |
1254 | 1258 | ||
1255 | return ret; | 1259 | return ret; |
@@ -1260,15 +1264,18 @@ static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep) | |||
1260 | struct dwc3_ep *dep = to_dwc3_ep(ep); | 1264 | struct dwc3_ep *dep = to_dwc3_ep(ep); |
1261 | struct dwc3 *dwc = dep->dwc; | 1265 | struct dwc3 *dwc = dep->dwc; |
1262 | unsigned long flags; | 1266 | unsigned long flags; |
1267 | int ret; | ||
1263 | 1268 | ||
1264 | spin_lock_irqsave(&dwc->lock, flags); | 1269 | spin_lock_irqsave(&dwc->lock, flags); |
1265 | dep->flags |= DWC3_EP_WEDGE; | 1270 | dep->flags |= DWC3_EP_WEDGE; |
1266 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
1267 | 1271 | ||
1268 | if (dep->number == 0 || dep->number == 1) | 1272 | if (dep->number == 0 || dep->number == 1) |
1269 | return dwc3_gadget_ep0_set_halt(ep, 1); | 1273 | ret = __dwc3_gadget_ep0_set_halt(ep, 1); |
1270 | else | 1274 | else |
1271 | return dwc3_gadget_ep_set_halt(ep, 1); | 1275 | ret = __dwc3_gadget_ep_set_halt(dep, 1, false); |
1276 | spin_unlock_irqrestore(&dwc->lock, flags); | ||
1277 | |||
1278 | return ret; | ||
1272 | } | 1279 | } |
1273 | 1280 | ||
1274 | /* -------------------------------------------------------------------------- */ | 1281 | /* -------------------------------------------------------------------------- */ |