Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ab59297 authored by Jack Pham's avatar Jack Pham
Browse files

usb: dwc3: gadget: Handle erratic error event only once



DWC3 databook suggests that upon receiving erratic error event
software should reset the controller. The way in which the
driver currently handles interrupts by offloading event processing
to a threaded handler could result in a long sequence of received
erratic errors in the event queue. dwc3_gadget_interrupt() could
then end up processing a large number of the same event unnecessarily.

In the case of dwc3-msm, this results in KERN_INFO messages flooding
the console. Fix this by only handling erratic error once. Add
a state variable to keep track of when it is seen, and clear it
once a non-error event is processed.

Change-Id: I5deeb2a614f9002867472a0e4aa26a61f0413ceb
Signed-off-by: default avatarJack Pham <jackp@codeaurora.org>
parent d3dde527
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -722,6 +722,7 @@ struct dwc3_scratchpad_array {
 * @hwparams: copy of hwparams registers
 * @root: debugfs root folder pointer
 * @tx_fifo_size: Available RAM size for TX fifo allocation
 * @err_evt_seen: previous event in queue was erratic error
 */
struct dwc3 {
	struct usb_ctrlrequest	*ctrl_req;
@@ -827,6 +828,7 @@ struct dwc3 {

	bool			nominal_elastic_buffer;
	bool			core_reset_after_phy_init;
	bool			err_evt_seen;
};

/* -------------------------------------------------------------------------- */
+7 −3
Original line number Diff line number Diff line
@@ -2861,9 +2861,11 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
		dev_vdbg(dwc->dev, "Start of Periodic Frame\n");
		break;
	case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
		if (!dwc->err_evt_seen) {
			dbg_event(0xFF, "ERROR", 0);
			dev_vdbg(dwc->dev, "Erratic Error\n");
			dwc3_dump_reg_info(dwc);
		}
		break;
	case DWC3_DEVICE_EVENT_CMD_CMPL:
		dev_vdbg(dwc->dev, "Command Complete\n");
@@ -2903,6 +2905,8 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
	default:
		dev_dbg(dwc->dev, "UNKNOWN IRQ %d\n", event->type);
	}

	dwc->err_evt_seen = (event->type == DWC3_DEVICE_EVENT_ERRATIC_ERROR);
}

static void dwc3_process_event_entry(struct dwc3 *dwc,