From patchwork Fri Apr 22 02:22:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 12822669 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4058C433EF for ; Fri, 22 Apr 2022 02:22:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443307AbiDVCZh (ORCPT ); Thu, 21 Apr 2022 22:25:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59834 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1443283AbiDVCZh (ORCPT ); Thu, 21 Apr 2022 22:25:37 -0400 Received: from smtprelay-out1.synopsys.com (smtprelay-out1.synopsys.com [149.117.73.133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 049F7496A1 for ; Thu, 21 Apr 2022 19:22:46 -0700 (PDT) Received: from mailhost.synopsys.com (sv1-mailhost2.synopsys.com [10.205.2.132]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client CN "mailhost.synopsys.com", Issuer "SNPSica2" (verified OK)) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id DA76341EEC; Fri, 22 Apr 2022 02:22:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1650594165; bh=uiTQ0No13gZ3HLJJPFyYU5ZQejy6aqUOpZmNrro/1jk=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=US4GqsGaYMmy8fyND1JhyVo2g6rvp8nvTE2wx7QvHkl0Y34lpHxVuP49IYfZ4xHSw R4BeRBcTYEpsqo3m+QjKXC1uAMAG+FuCvdg9DnQboOEdrHMEl2VFPilNiA5SRAQrvf UtLoxpYgEJ2Cd5tzDuj5Ml48asoGOuioef11v/BLV5sN85avVUBj9pQIuy+L50fewx 26Vj0laQWDD5IdSVOXQ2nURZFDxKHOcykRNLh6mb5Ovc/DQU22RWTKDtZPe9NR/UDX C0fdKlHSn1pWsWY365CLcI/ryw+YWdPGdVloSSspxdO5PQ/B7s2ecxmVCxLJxfe6mC AfhEE+gY0SLaA== Received: from te-lab16-v2 (nanobot.internal.synopsys.com [10.204.48.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mailhost.synopsys.com (Postfix) with ESMTPSA id BED64A006F; Fri, 22 Apr 2022 02:22:44 +0000 (UTC) Received: by te-lab16-v2 (sSMTP sendmail emulation); Thu, 21 Apr 2022 19:22:44 -0700 Date: Thu, 21 Apr 2022 19:22:44 -0700 Message-Id: In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH 3/6] usb: dwc3: gadget: Don't modify GEVNTCOUNT in pullup() To: Felipe Balbi , Greg Kroah-Hartman , linux-usb@vger.kernel.org Cc: John Youn , Thinh Nguyen , Wesley Cheng Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org If the GEVNTCOUNT indicates events in the event buffer, the driver needs to acknowledge them before the controller can halt. Simply let the interrupt handler acknowledges the remaining event generated by the controller while polling for DSTS.DEVCTLHLT. This avoids disabling irq and taking care of race condition between the interrupt handlers and pullup(). Signed-off-by: Thinh Nguyen --- drivers/usb/dwc3/gadget.c | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index d8e95196967c..a86225dbaa2c 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2500,8 +2500,9 @@ static int __dwc3_gadget_start(struct dwc3 *dwc); static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc) { - u32 count; + unsigned long flags; + spin_lock_irqsave(&dwc->lock, flags); dwc->connected = false; /* @@ -2513,29 +2514,21 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc) */ dwc3_stop_active_transfers(dwc); __dwc3_gadget_stop(dwc); + spin_unlock_irqrestore(&dwc->lock, flags); /* - * In the Synopsys DesignWare Cores USB3 Databook Rev. 3.30a - * Section 1.3.4, it mentions that for the DEVCTRLHLT bit, the - * "software needs to acknowledge the events that are generated - * (by writing to GEVNTCOUNTn) while it is waiting for this bit - * to be set to '1'." + * Note: if the GEVNTCOUNT indicates events in the event buffer, the + * driver needs to acknowledge them before the controller can halt. + * Simply let the interrupt handler acknowledges and handle the + * remaining event generated by the controller while polling for + * DSTS.DEVCTLHLT. */ - count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); - count &= DWC3_GEVNTCOUNT_MASK; - if (count > 0) { - dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count); - dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % - dwc->ev_buf->length; - } - return dwc3_gadget_run_stop(dwc, false, false); } static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) { struct dwc3 *dwc = gadget_to_dwc(g); - unsigned long flags; int ret; is_on = !!is_on; @@ -2579,14 +2572,6 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) return 0; } - /* - * Synchronize and disable any further event handling while controller - * is being enabled/disabled. - */ - disable_irq(dwc->irq_gadget); - - spin_lock_irqsave(&dwc->lock, flags); - if (!is_on) { ret = dwc3_gadget_soft_disconnect(dwc); } else { @@ -2596,16 +2581,12 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) * device-initiated disconnect requires a core soft reset * (DCTL.CSftRst) before enabling the run/stop bit. */ - spin_unlock_irqrestore(&dwc->lock, flags); dwc3_core_soft_reset(dwc); - spin_lock_irqsave(&dwc->lock, flags); dwc3_event_buffers_setup(dwc); __dwc3_gadget_start(dwc); ret = dwc3_gadget_run_stop(dwc, true, false); } - spin_unlock_irqrestore(&dwc->lock, flags); - enable_irq(dwc->irq_gadget); pm_runtime_put(dwc->dev);