lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 12 Jan 2018 12:00:16 +0800
From:   William Wu <william.wu@...k-chips.com>
To:     balbi@...nel.org, gregkh@...uxfoundation.org
Cc:     heiko@...ech.de, linux-kernel@...r.kernel.org,
        linux-usb@...r.kernel.org, linux-rockchip@...ts.infradead.org,
        frank.wang@...k-chips.com, huangtao@...k-chips.com,
        dianders@...gle.com, briannorris@...gle.com, groeck@...gle.com,
        daniel.meng@...k-chips.com, John.Youn@...opsys.com,
        william.wu@...k-chips.com, lin.huang@...k-chips.com
Subject: [PATCH] usb: dwc3: core: power on PHYs before initializing core

The dwc3_core_init() gets the PHYs and initializes the PHYs with
the usb_phy_init() and phy_init() functions before initializing
core, and power on the PHYs after core initialization is done.

However, some platforms (e.g. Rockchip RK3399 DWC3 with Type-C
USB3 PHY), it needs to do some special operation while power on
the Type-C PHY before initializing DWC3 core. It's because that
the RK3399 Type-C PHY requires to hold the DWC3 controller in
reset state to keep the PIPE power state in P2 while configuring
the Type-C PHY, otherwise, it may cause waiting for the PIPE ready
timeout. In this case, if we power on the PHYs after the DWC3 core
initialization is done, the core will be reset to uninitialized
state after power on the PHYs.

Fix this by powering on the PHYs before initializing core. And
because the GUID register may also be reset in this case, so we
need to configure the GUID register after powering on the PHYs.

Signed-off-by: William Wu <william.wu@...k-chips.com>
---
 drivers/usb/dwc3/core.c | 46 ++++++++++++++++++++++------------------------
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index c32d2b9..4f5573f 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -741,12 +741,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
 		goto err0;
 	}
 
-	/*
-	 * Write Linux Version Code to our GUID register so it's easy to figure
-	 * out which kernel version a bug was found.
-	 */
-	dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
-
 	/* Handle USB2.0-only core configuration */
 	if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
 			DWC3_GHWPARAMS3_SSPHY_IFC_DIS) {
@@ -762,34 +756,40 @@ static int dwc3_core_init(struct dwc3 *dwc)
 	if (ret)
 		goto err0;
 
+	usb_phy_set_suspend(dwc->usb2_phy, 0);
+	usb_phy_set_suspend(dwc->usb3_phy, 0);
+	ret = phy_power_on(dwc->usb2_generic_phy);
+	if (ret < 0)
+		goto err1;
+
+	ret = phy_power_on(dwc->usb3_generic_phy);
+	if (ret < 0)
+		goto err2;
+
 	ret = dwc3_phy_setup(dwc);
 	if (ret)
-		goto err0;
+		goto err3;
+
+	/*
+	 * Write Linux Version Code to our GUID register so it's easy to figure
+	 * out which kernel version a bug was found.
+	 */
+	dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
 
 	dwc3_core_setup_global_control(dwc);
 	dwc3_core_num_eps(dwc);
 
 	ret = dwc3_setup_scratch_buffers(dwc);
 	if (ret)
-		goto err1;
+		goto err3;
 
 	/* Adjust Frame Length */
 	dwc3_frame_length_adjustment(dwc);
 
-	usb_phy_set_suspend(dwc->usb2_phy, 0);
-	usb_phy_set_suspend(dwc->usb3_phy, 0);
-	ret = phy_power_on(dwc->usb2_generic_phy);
-	if (ret < 0)
-		goto err2;
-
-	ret = phy_power_on(dwc->usb3_generic_phy);
-	if (ret < 0)
-		goto err3;
-
 	ret = dwc3_event_buffers_setup(dwc);
 	if (ret) {
 		dev_err(dwc->dev, "failed to setup event buffers\n");
-		goto err4;
+		goto err3;
 	}
 
 	/*
@@ -821,17 +821,15 @@ static int dwc3_core_init(struct dwc3 *dwc)
 
 	return 0;
 
-err4:
+err3:
 	phy_power_off(dwc->usb3_generic_phy);
 
-err3:
+err2:
 	phy_power_off(dwc->usb2_generic_phy);
 
-err2:
+err1:
 	usb_phy_set_suspend(dwc->usb2_phy, 1);
 	usb_phy_set_suspend(dwc->usb3_phy, 1);
-
-err1:
 	usb_phy_shutdown(dwc->usb2_phy);
 	usb_phy_shutdown(dwc->usb3_phy);
 	phy_exit(dwc->usb2_generic_phy);
-- 
2.0.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ