[PATCH v3 05/16] phy: qcom-qmp: Fix PHY block reset sequence

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



PHY block or asynchronous reset requires signal
to be asserted before de-asserting. Driver is only
de-asserting signal which is already low, hence
reset operation is a no-op. Fix this by asserting
signal first. Also, resetting requires PHY clocks
to be turned ON only after reset is finished. Fix
that as well.

Signed-off-by: Manu Gautam <mgautam@xxxxxxxxxxxxxx>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 2f427e3..aa27757 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -739,13 +739,16 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 		return ret;
 	}
 
-	ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
-	if (ret) {
-		dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
-		goto err_clk_enable;
+	for (i = 0; i < cfg->num_resets; i++) {
+		ret = reset_control_assert(qmp->resets[i]);
+		if (ret) {
+			dev_err(qmp->dev, "%s reset assert failed\n",
+				cfg->reset_list[i]);
+			goto err_rst_assert;
+		}
 	}
 
-	for (i = 0; i < cfg->num_resets; i++) {
+	for (i = cfg->num_resets - 1; i >= 0; i--) {
 		ret = reset_control_deassert(qmp->resets[i]);
 		if (ret) {
 			dev_err(qmp->dev, "%s reset deassert failed\n",
@@ -754,6 +757,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 		}
 	}
 
+	ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
+	if (ret) {
+		dev_err(qmp->dev, "failed to enable clks, err=%d\n", ret);
+		goto err_rst;
+	}
+
 	if (cfg->has_phy_com_ctrl)
 		qphy_setbits(serdes, cfg->regs[QPHY_COM_POWER_DOWN_CONTROL],
 			     SW_PWRDN);
@@ -778,7 +787,7 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 		if (ret) {
 			dev_err(qmp->dev,
 				"phy common block init timed-out\n");
-			goto err_rst;
+			goto err_com_init;
 		}
 	}
 
@@ -786,11 +795,12 @@ static int qcom_qmp_phy_com_init(struct qcom_qmp *qmp)
 
 	return 0;
 
+err_com_init:
+	clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
 err_rst:
-	while (--i >= 0)
+	while (++i < cfg->num_resets)
 		reset_control_assert(qmp->resets[i]);
-	clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
-err_clk_enable:
+err_rst_assert:
 	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
 	mutex_unlock(&qmp->phy_mutex);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux