From patchwork Fri Apr 16 12:48:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Petrosyan X-Patchwork-Id: 423673 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D2BBC433ED for ; Fri, 16 Apr 2021 12:48:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4977D61107 for ; Fri, 16 Apr 2021 12:48:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243764AbhDPMs7 (ORCPT ); Fri, 16 Apr 2021 08:48:59 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:38478 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242267AbhDPMsz (ORCPT ); Fri, 16 Apr 2021 08:48:55 -0400 Received: from mailhost.synopsys.com (mdc-mailhost2.synopsys.com [10.225.0.210]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 709EC40E1C; Fri, 16 Apr 2021 12:48:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1618577310; bh=Kr2xNeU4OXF1sHy3UEwMqt5On5AMSUd5JRZZcuAfDNk=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=btBDN3YdtgxaC9rwpE+4voT8g5XzmlTc+kCzduaa307x2Lbi8FE/54EqPfI/PDPDw 6CpKJFhD8Vzo1aALfpTpHUotiluGaP4LlKSglq1Iz6gEcfbmrN3ttZnUBTU7nNe1Bo ga0A/8E7+ioc23U4SXgIwFCEzLZ1U6XtPzfhwt1YWpfbPgWd+wpX0P8mMEfzCF/Mt6 WVjuQpWwF+CM1huPuyj4oi6LJufXCgsb7J3cJt6GW4QYDVLeKBVRfcuvbDXA4MzR1b 5H54JGZIKfrm8YEhHodpXr6vEYCBrG382GveaZd+jXFLXsnacc1pUx4v5nlLMIH4qr uixtv27y6MqjQ== Received: from razpc-HP (razpc-hp.internal.synopsys.com [10.116.126.207]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 9BB59A005D; Fri, 16 Apr 2021 12:48:27 +0000 (UTC) Received: by razpc-HP (sSMTP sendmail emulation); Fri, 16 Apr 2021 16:48:26 +0400 Date: Fri, 16 Apr 2021 16:48:26 +0400 In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Artur Petrosyan Subject: [PATCH v2 13/15] usb: dwc2: Add exit hibernation mode before removing drive To: Felipe Balbi , Greg Kroah-Hartman , Minas Harutyunyan , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Cc: John Youn , Artur Petrosyan Message-Id: <20210416124827.9BB59A005D@mailhost.synopsys.com> Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org When dwc2 core is in hibernation mode loading driver again causes driver fail. Because in that mode registers are not accessible. In order to exit from hibernation checking dwc2 core power saving state in "dwc2_driver_remove()" function. If core is in hibernation, then checking the operational mode of the driver. To check whether dwc2 core is operating in host mode or device mode there is one way which is retrieving the backup value of "gotgctl" and compare the "CurMod" value. If previously core entered hibernation in host mode then the exit is performed for host if not then exit is performed for device mode. The introduced checking is because in hibernation state all registers are not accessible. Signed-off-by: Artur Petrosyan Reported-by: kernel test robot Reported-by: Dan Carpenter Acked-by: Minas Harutyunyan --- drivers/usb/dwc2/platform.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index f8b819cfa80e..8ad33e042a14 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -316,8 +316,23 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) static int dwc2_driver_remove(struct platform_device *dev) { struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); + struct dwc2_gregs_backup *gr; int ret = 0; + gr = &hsotg->gr_backup; + + /* Exit Hibernation when driver is removed. */ + if (hsotg->hibernated) { + if (gr->gotgctl & GOTGCTL_CURMODE_HOST) + ret = dwc2_exit_hibernation(hsotg, 0, 0, 1); + else + ret = dwc2_exit_hibernation(hsotg, 0, 0, 0); + + if (ret) + dev_err(hsotg->dev, + "exit hibernation failed.\n"); + } + /* Exit Partial Power Down when driver is removed. */ if (hsotg->in_ppd) { ret = dwc2_exit_partial_power_down(hsotg, 0, true);