Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp3699470imm; Wed, 5 Sep 2018 04:42:07 -0700 (PDT) X-Google-Smtp-Source: ANB0Vdb2+54ceCuTbB9b23ykTLqHpNO8/7o/vsgB70vz6d7eSyFD6qHEo4BeI+biJSXhgdr9O2Wb X-Received: by 2002:a62:565c:: with SMTP id k89-v6mr39915271pfb.212.1536147726945; Wed, 05 Sep 2018 04:42:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536147726; cv=none; d=google.com; s=arc-20160816; b=dFN/4nqUxhFBcrlG9nkm1YNYjq/qKLUha7g4YgV7lJ1RyQZAdZ7qec65r7S6prqjxk BVoptOzJWpBx5hXH7OYdTrtwsPhrlCt9JAcLwMBTMoM31vdauaAOkN5alyeA05d2r56F cebKsdIZLE7CT1pbZq0AfqpEQxJts876s9T0+1jbHqTYLNhpLvUAocvL7po32tStU7Q0 CYUZQ4Fmp9SvinWCNRUEdwCsX0WhtSetIEVeEDQZk5yPLH9erqECk02XZ+Sp1fOHKe29 xcJAmFXuaffkLfTyuGr7/kjcrCYoHM6w8hvOCNm72iwbtyTre9GsuDYBuSRIowAtm0it FUvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=aGxWcd9tafGQyQwXnI7uwRWjK/MUjBDfce19Vp7CE6E=; b=mNijtkj4pT81eNEAc7aeTKT19L0uCReTp4zIYB2vqWyZPkUFADRLyXj+4badEc36YC dTCOAUcRSdqDY0PO7MD8WChRLfOzkRHiyXIUPlBHQUe4xM/OqX1ugqtyPyH1RYaowias IfzhTslwIS4EjxhWgndAPAEBM/TEbrKxYZ7nBsFjDtFcG8+eKsB9xyFqj4R6G+hVYw34 Z25dB7i+8hl/5a0t+538ZQg1rwC9/r1V13U8btV+QYWm/j4yS5xDUy28pWg3QGSY6wky 1tjj0VlFc+Smu40fCMFlOnfEesplcoaQHGLICtsTDQIw8eCro/yHYrkmBDpWR8R/MpzE FkZw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c3-v6si1787491plz.21.2018.09.05.04.41.51; Wed, 05 Sep 2018 04:42:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727637AbeIEQKc (ORCPT + 99 others); Wed, 5 Sep 2018 12:10:32 -0400 Received: from mx08-00178001.pphosted.com ([91.207.212.93]:49825 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726008AbeIEQKZ (ORCPT ); Wed, 5 Sep 2018 12:10:25 -0400 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx08-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id w85BYILl018453; Wed, 5 Sep 2018 13:40:27 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-00178001.pphosted.com with ESMTP id 2macws8hmc-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 05 Sep 2018 13:40:27 +0200 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id D940731; Wed, 5 Sep 2018 11:40:26 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas23.st.com [10.75.90.46]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id A62622B83; Wed, 5 Sep 2018 11:40:26 +0000 (GMT) Received: from SAFEX1HUBCAS24.st.com (10.75.90.95) by SAFEX1HUBCAS23.st.com (10.75.90.46) with Microsoft SMTP Server (TLS) id 14.3.361.1; Wed, 5 Sep 2018 13:40:26 +0200 Received: from localhost (10.201.20.5) by webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.361.1; Wed, 5 Sep 2018 13:40:26 +0200 From: Amelie Delaunay To: Minas Harutyunyan , Felipe Balbi , Greg Kroah-Hartman CC: , , , Fabrice Gasnier , Amelie Delaunay Subject: [PATCH 4/4] usb: dwc2: fix unbalanced use of external vbus-supply Date: Wed, 5 Sep 2018 13:40:05 +0200 Message-ID: <1536147605-26279-5-git-send-email-amelie.delaunay@st.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1536147605-26279-1-git-send-email-amelie.delaunay@st.com> References: <1536147605-26279-1-git-send-email-amelie.delaunay@st.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.201.20.5] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-09-05_07:,, signatures=0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Fabrice Gasnier When using external vbus supply regulator, it should be enabled synchronously with PWR bit in HPRT register. This also fixes unbalanced use of this optional regulator (This can be reproduced easily when unbinding the driver). Fixes: 531ef5ebea96 ("usb: dwc2: add support for host mode external vbus supply") Signed-off-by: Fabrice Gasnier Signed-off-by: Amelie Delaunay --- drivers/usb/dwc2/hcd.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index e8a480e..8efbb45 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3558,6 +3558,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, u32 port_status; u32 speed; u32 pcgctl; + u32 pwr; switch (typereq) { case ClearHubFeature: @@ -3606,8 +3607,11 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, dev_dbg(hsotg->dev, "ClearPortFeature USB_PORT_FEAT_POWER\n"); hprt0 = dwc2_read_hprt0(hsotg); + pwr = hprt0 & HPRT0_PWR; hprt0 &= ~HPRT0_PWR; dwc2_writel(hsotg, hprt0, HPRT0); + if (pwr) + dwc2_vbus_supply_exit(hsotg); break; case USB_PORT_FEAT_INDICATOR: @@ -3817,8 +3821,11 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, dev_dbg(hsotg->dev, "SetPortFeature - USB_PORT_FEAT_POWER\n"); hprt0 = dwc2_read_hprt0(hsotg); + pwr = hprt0 & HPRT0_PWR; hprt0 |= HPRT0_PWR; dwc2_writel(hsotg, hprt0, HPRT0); + if (!pwr) + dwc2_vbus_supply_init(hsotg); break; case USB_PORT_FEAT_RESET: @@ -3835,6 +3842,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, dwc2_writel(hsotg, 0, PCGCTL); hprt0 = dwc2_read_hprt0(hsotg); + pwr = hprt0 & HPRT0_PWR; /* Clear suspend bit if resetting from suspend state */ hprt0 &= ~HPRT0_SUSP; @@ -3848,6 +3856,8 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, dev_dbg(hsotg->dev, "In host mode, hprt0=%08x\n", hprt0); dwc2_writel(hsotg, hprt0, HPRT0); + if (!pwr) + dwc2_vbus_supply_init(hsotg); } /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */ @@ -4387,6 +4397,7 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd) struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); struct usb_bus *bus = hcd_to_bus(hcd); unsigned long flags; + u32 hprt0; int ret; dev_dbg(hsotg->dev, "DWC OTG HCD START\n"); @@ -4403,12 +4414,16 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd) dwc2_hcd_reinit(hsotg); - /* enable external vbus supply before resuming root hub */ - spin_unlock_irqrestore(&hsotg->lock, flags); - ret = dwc2_vbus_supply_init(hsotg); - if (ret) - return ret; - spin_lock_irqsave(&hsotg->lock, flags); + hprt0 = dwc2_read_hprt0(hsotg); + /* Has vbus power been turned on in dwc2_core_host_init ? */ + if (hprt0 & HPRT0_PWR) { + /* Enable external vbus supply before resuming root hub */ + spin_unlock_irqrestore(&hsotg->lock, flags); + ret = dwc2_vbus_supply_init(hsotg); + if (ret) + return ret; + spin_lock_irqsave(&hsotg->lock, flags); + } /* Initialize and connect root hub if one is not already attached */ if (bus->root_hub) { @@ -4430,6 +4445,7 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) { struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); unsigned long flags; + u32 hprt0; /* Turn off all host-specific interrupts */ dwc2_disable_host_interrupts(hsotg); @@ -4438,6 +4454,7 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) synchronize_irq(hcd->irq); spin_lock_irqsave(&hsotg->lock, flags); + hprt0 = dwc2_read_hprt0(hsotg); /* Ensure hcd is disconnected */ dwc2_hcd_disconnect(hsotg, true); dwc2_hcd_stop(hsotg); @@ -4446,7 +4463,9 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); spin_unlock_irqrestore(&hsotg->lock, flags); - dwc2_vbus_supply_exit(hsotg); + /* keep balanced supply init/exit by checking HPRT0_PWR */ + if (hprt0 & HPRT0_PWR) + dwc2_vbus_supply_exit(hsotg); usleep_range(1000, 3000); } -- 2.7.4