aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3/gadget.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/dwc3/gadget.c')
-rw-r--r--drivers/usb/dwc3/gadget.c83
1 files changed, 77 insertions, 6 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 70715eeededd..9d64dd02c57e 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -298,11 +298,76 @@ static const char *dwc3_gadget_ep_cmd_string(u8 cmd)
298 } 298 }
299} 299}
300 300
301static const char *dwc3_gadget_generic_cmd_string(u8 cmd)
302{
303 switch (cmd) {
304 case DWC3_DGCMD_SET_LMP:
305 return "Set LMP";
306 case DWC3_DGCMD_SET_PERIODIC_PAR:
307 return "Set Periodic Parameters";
308 case DWC3_DGCMD_XMIT_FUNCTION:
309 return "Transmit Function Wake Device Notification";
310 case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO:
311 return "Set Scratchpad Buffer Array Address Lo";
312 case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI:
313 return "Set Scratchpad Buffer Array Address Hi";
314 case DWC3_DGCMD_SELECTED_FIFO_FLUSH:
315 return "Selected FIFO Flush";
316 case DWC3_DGCMD_ALL_FIFO_FLUSH:
317 return "All FIFO Flush";
318 case DWC3_DGCMD_SET_ENDPOINT_NRDY:
319 return "Set Endpoint NRDY";
320 case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK:
321 return "Run SoC Bus Loopback Test";
322 default:
323 return "UNKNOWN";
324 }
325}
326
327static const char *dwc3_gadget_link_string(enum dwc3_link_state link_state)
328{
329 switch (link_state) {
330 case DWC3_LINK_STATE_U0:
331 return "U0";
332 case DWC3_LINK_STATE_U1:
333 return "U1";
334 case DWC3_LINK_STATE_U2:
335 return "U2";
336 case DWC3_LINK_STATE_U3:
337 return "U3";
338 case DWC3_LINK_STATE_SS_DIS:
339 return "SS.Disabled";
340 case DWC3_LINK_STATE_RX_DET:
341 return "RX.Detect";
342 case DWC3_LINK_STATE_SS_INACT:
343 return "SS.Inactive";
344 case DWC3_LINK_STATE_POLL:
345 return "Polling";
346 case DWC3_LINK_STATE_RECOV:
347 return "Recovery";
348 case DWC3_LINK_STATE_HRESET:
349 return "Hot Reset";
350 case DWC3_LINK_STATE_CMPLY:
351 return "Compliance";
352 case DWC3_LINK_STATE_LPBK:
353 return "Loopback";
354 case DWC3_LINK_STATE_RESET:
355 return "Reset";
356 case DWC3_LINK_STATE_RESUME:
357 return "Resume";
358 default:
359 return "UNKNOWN link state\n";
360 }
361}
362
301int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param) 363int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param)
302{ 364{
303 u32 timeout = 500; 365 u32 timeout = 500;
304 u32 reg; 366 u32 reg;
305 367
368 dev_vdbg(dwc->dev, "generic cmd '%s' [%d] param %08x\n",
369 dwc3_gadget_generic_cmd_string(cmd), cmd, param);
370
306 dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param); 371 dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param);
307 dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT); 372 dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
308 373
@@ -332,9 +397,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
332 u32 timeout = 500; 397 u32 timeout = 500;
333 u32 reg; 398 u32 reg;
334 399
335 dev_vdbg(dwc->dev, "%s: cmd '%s' params %08x %08x %08x\n", 400 dev_vdbg(dwc->dev, "%s: cmd '%s' [%d] params %08x %08x %08x\n",
336 dep->name, 401 dep->name,
337 dwc3_gadget_ep_cmd_string(cmd), params->param0, 402 dwc3_gadget_ep_cmd_string(cmd), cmd, params->param0,
338 params->param1, params->param2); 403 params->param1, params->param2);
339 404
340 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0); 405 dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
@@ -515,7 +580,7 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
515{ 580{
516 struct dwc3 *dwc = dep->dwc; 581 struct dwc3 *dwc = dep->dwc;
517 u32 reg; 582 u32 reg;
518 int ret = -ENOMEM; 583 int ret;
519 584
520 dev_vdbg(dwc->dev, "Enabling %s\n", dep->name); 585 dev_vdbg(dwc->dev, "Enabling %s\n", dep->name);
521 586
@@ -604,6 +669,10 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
604 669
605 dwc3_remove_requests(dwc, dep); 670 dwc3_remove_requests(dwc, dep);
606 671
672 /* make sure HW endpoint isn't stalled */
673 if (dep->flags & DWC3_EP_STALL)
674 __dwc3_gadget_ep_set_halt(dep, 0);
675
607 reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); 676 reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
608 reg &= ~DWC3_DALEPENA_EP(dep->number); 677 reg &= ~DWC3_DALEPENA_EP(dep->number);
609 dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); 678 dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
@@ -2441,8 +2510,6 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
2441 } 2510 }
2442 } 2511 }
2443 2512
2444 dwc->link_state = next;
2445
2446 switch (next) { 2513 switch (next) {
2447 case DWC3_LINK_STATE_U1: 2514 case DWC3_LINK_STATE_U1:
2448 if (dwc->speed == USB_SPEED_SUPER) 2515 if (dwc->speed == USB_SPEED_SUPER)
@@ -2460,7 +2527,11 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
2460 break; 2527 break;
2461 } 2528 }
2462 2529
2463 dev_vdbg(dwc->dev, "%s link %d\n", __func__, dwc->link_state); 2530 dev_vdbg(dwc->dev, "link change: %s [%d] -> %s [%d]\n",
2531 dwc3_gadget_link_string(dwc->link_state),
2532 dwc->link_state, dwc3_gadget_link_string(next), next);
2533
2534 dwc->link_state = next;
2464} 2535}
2465 2536
2466static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc, 2537static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc,