With the upcoming introduction of USB Type-C orientation switching the region of mutual exclusion needs to be extended to cover both the common init/exit as well as the individual functions. So move the phy_mutex one step up the stack. Signed-off-by: Bjorn Andersson <quic_bjorande@xxxxxxxxxxx> Reviewed-by: Johan Hovold <johan+linaro@xxxxxxxxxx> Tested-by: Abel Vesa <abel.vesa@xxxxxxxxxx> Tested-by: Steev Klimaszewski <steev@xxxxxxxx> Tested-by: Neil Armstrong <neil.armstrong@xxxxxxxxxx> # on HDK8450 Tested-by: Johan Hovold <johan+linaro@xxxxxxxxxx> # X13s --- Changes since v1: - Rebased on Johan's init_count fixes drivers/phy/qualcomm/phy-qcom-qmp-combo.c | 47 ++++++++++++++--------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index 87b17e5877ab..8918ba2b18a4 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -2463,11 +2463,8 @@ static int qmp_combo_com_init(struct qmp_combo *qmp) void __iomem *com = qmp->com; int ret; - mutex_lock(&qmp->phy_mutex); - if (qmp->init_count++) { - mutex_unlock(&qmp->phy_mutex); + if (qmp->init_count++) return 0; - } ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); if (ret) { @@ -2514,8 +2511,6 @@ static int qmp_combo_com_init(struct qmp_combo *qmp) qphy_setbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); - mutex_unlock(&qmp->phy_mutex); - return 0; err_assert_reset: @@ -2524,7 +2519,6 @@ static int qmp_combo_com_init(struct qmp_combo *qmp) regulator_bulk_disable(cfg->num_vregs, qmp->vregs); err_decrement_count: qmp->init_count--; - mutex_unlock(&qmp->phy_mutex); return ret; } @@ -2533,11 +2527,8 @@ static int qmp_combo_com_exit(struct qmp_combo *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; - mutex_lock(&qmp->phy_mutex); - if (--qmp->init_count) { - mutex_unlock(&qmp->phy_mutex); + if (--qmp->init_count) return 0; - } reset_control_bulk_assert(cfg->num_resets, qmp->resets); @@ -2545,8 +2536,6 @@ static int qmp_combo_com_exit(struct qmp_combo *qmp) regulator_bulk_disable(cfg->num_vregs, qmp->vregs); - mutex_unlock(&qmp->phy_mutex); - return 0; } @@ -2556,21 +2545,29 @@ static int qmp_combo_dp_init(struct phy *phy) const struct qmp_phy_cfg *cfg = qmp->cfg; int ret; + mutex_lock(&qmp->phy_mutex); + ret = qmp_combo_com_init(qmp); if (ret) - return ret; + goto out_unlock; cfg->dp_aux_init(qmp); - return 0; +out_unlock: + mutex_unlock(&qmp->phy_mutex); + return ret; } static int qmp_combo_dp_exit(struct phy *phy) { struct qmp_combo *qmp = phy_get_drvdata(phy); + mutex_lock(&qmp->phy_mutex); + qmp_combo_com_exit(qmp); + mutex_unlock(&qmp->phy_mutex); + return 0; } @@ -2687,14 +2684,19 @@ static int qmp_combo_usb_init(struct phy *phy) struct qmp_combo *qmp = phy_get_drvdata(phy); int ret; + mutex_lock(&qmp->phy_mutex); ret = qmp_combo_com_init(qmp); if (ret) - return ret; + goto out_unlock; ret = qmp_combo_usb_power_on(phy); - if (ret) + if (ret) { qmp_combo_com_exit(qmp); + goto out_unlock; + } +out_unlock: + mutex_unlock(&qmp->phy_mutex); return ret; } @@ -2703,11 +2705,18 @@ static int qmp_combo_usb_exit(struct phy *phy) struct qmp_combo *qmp = phy_get_drvdata(phy); int ret; + mutex_lock(&qmp->phy_mutex); ret = qmp_combo_usb_power_off(phy); if (ret) - return ret; + goto out_unlock; - return qmp_combo_com_exit(qmp); + ret = qmp_combo_com_exit(qmp); + if (ret) + goto out_unlock; + +out_unlock: + mutex_unlock(&qmp->phy_mutex); + return ret; } static int qmp_combo_usb_set_mode(struct phy *phy, enum phy_mode mode, int submode) -- 2.39.2