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

Commit 80c2ae83 authored by Lena Salman's avatar Lena Salman Committed by Gerrit - the friendly Code Review server
Browse files

drivers: usb: dwc3: Remove xfer timer when going to suspend



When in the middle of processing bulk transfers we get a
suspend event, we still continue to arm the bulk transfer timer
because we didn't finish the bulk transfer.
However we are going to suspend initiated by the host (sleep),
and the device does go to LPM thus causing the transfer_complete
function running when clocks are off and resulting in unclocked access.
This patch makes sure we do pm_runtime_get the device before
accessing registers, and doesn't arm the timer again when we are
in suspend state.

CRs-fixed: 746587
Change-Id: I9491e360cd2ea29d569e2a8a7da771f29ec946b3
Signed-off-by: default avatarLena Salman <esalman@codeaurora.org>
parent f1a9f6d4
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -2260,6 +2260,7 @@ static enum hrtimer_restart dwc3_gadget_ep_timer(struct hrtimer *hrtimer)
{
	struct dwc3_ep *dep = container_of(hrtimer, struct dwc3_ep, xfer_timer);
	struct dwc3_event_depevt event;
	unsigned long flags;
	struct dwc3 *dwc;

	if (!dep) {
@@ -2282,9 +2283,12 @@ static enum hrtimer_restart dwc3_gadget_ep_timer(struct hrtimer *hrtimer)

	event.status = 0;

	spin_lock(&dwc->lock);
	spin_lock_irqsave(&dwc->lock, flags);

	if (!(atomic_read(&dwc->in_lpm)))
		dwc3_endpoint_transfer_complete(dep->dwc, dep, &event, 1);
	spin_unlock(&dwc->lock);

	spin_unlock_irqrestore(&dwc->lock, flags);

out:
	return HRTIMER_NORESTART;
@@ -2584,10 +2588,13 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
		 * If this is ISR (LST) racing with hr_timer then timer_cancel
		 * will fail and there is a possibility that timer gets re-armed
		 * But, clean_busy check would ensure timer is not armed again.
		 * Also, in case we're suspended (DWC3_LINK_STATE_U3), don't arm
		 * the timer.
		 */

		if (event->status & DEPEVT_STATUS_LST)
			hrtimer_try_to_cancel(&dep->xfer_timer);
		else if (!clean_busy)
		else if (!clean_busy && (dwc->link_state != DWC3_LINK_STATE_U3))
			hrtimer_start(&dep->xfer_timer, ktime_set(0,
				bulk_ep_xfer_timeout_ms * NSEC_PER_MSEC),
				HRTIMER_MODE_REL);