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 <mgau...@codeaurora.org>
---
 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-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to