[PATCH 5/5] usb: dwc3: xilinx: unwind ZynqMP platform init on probe failure and remove

Radhey Shyam Pandey <[email protected]>
Newsgroups org.kernel.vger.linux-kernel,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-usb
Message-ID <[email protected]>
Add dwc3_xlnx_exit_zynqmp() and wire it as the ZynqMP platform exit
callback. If probe steps fail after a successful plat->init(), call
plat->exit() to re-assert released resets and unwind the PHY before
disabling clocks. Call the same callback from remove() and shutdown.

Fixes: 84770f028fab ("usb: dwc3: Add driver for Xilinx platforms")
Signed-off-by: Radhey Shyam Pandey <[email protected]>
---
 drivers/usb/dwc3/dwc3-xilinx.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
index 38613553937e..0d2232741d46 100644
--- a/drivers/usb/dwc3/dwc3-xilinx.c
+++ b/drivers/usb/dwc3/dwc3-xilinx.c
@@ -121,6 +121,20 @@ static int dwc3_xlnx_init_versal(struct dwc3_xlnx *priv_data)
 	return 0;
 }
 
+static void dwc3_xlnx_exit_zynqmp(struct dwc3_xlnx *priv_data)
+{
+	phy_power_off(priv_data->usb3_phy);
+
+	if (priv_data->usb_resets_released) {
+		reset_control_assert(priv_data->usb_hibrst);
+		reset_control_assert(priv_data->usb_crst);
+		reset_control_assert(priv_data->usb_apbrst);
+		priv_data->usb_resets_released = false;
+	}
+
+	phy_exit(priv_data->usb3_phy);
+}
+
 static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
 {
 	struct device		*dev = priv_data->dev;
@@ -257,6 +271,7 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data)
 
 static const struct dwc3_xlnx_platdata zynqmp_platdata = {
 	.init = dwc3_xlnx_init_zynqmp,
+	.exit = dwc3_xlnx_exit_zynqmp,
 };
 
 static const struct dwc3_xlnx_platdata versal_platdata = {
@@ -346,11 +361,11 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
 
 	ret = dwc3_set_swnode(dev);
 	if (ret)
-		goto err_clk_put;
+		goto err_pltfm_exit;
 
 	ret = of_platform_populate(np, NULL, NULL, dev);
 	if (ret)
-		goto err_clk_put;
+		goto err_pltfm_exit;
 
 	pm_runtime_set_active(dev);
 	ret = devm_pm_runtime_enable(dev);
@@ -367,7 +382,9 @@ static int dwc3_xlnx_probe(struct platform_device *pdev)
 err_pm_set_suspended:
 	of_platform_depopulate(dev);
 	pm_runtime_set_suspended(dev);
-
+err_pltfm_exit:
+	if (priv_data->plat->exit)
+		priv_data->plat->exit(priv_data);
 err_clk_put:
 	clk_bulk_disable_unprepare(priv_data->num_clocks, priv_data->clks);
 
@@ -381,6 +398,9 @@ static void dwc3_xlnx_remove(struct platform_device *pdev)
 
 	of_platform_depopulate(dev);
 
+	if (priv_data->plat->exit)
+		priv_data->plat->exit(priv_data);
+
 	clk_bulk_disable_unprepare(priv_data->num_clocks, priv_data->clks);
 	priv_data->num_clocks = 0;
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.