diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c index 799c0bf199c5..ca297117de6e 100644 --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -3915,18 +3915,20 @@ int smblib_get_prop_typec_power_role(struct smb_charger *chg, int *val) return 0; } + spin_lock(&chg->typec_pr_lock); + rc = smblib_read(chg, TYPE_C_MODE_CFG_REG, &ctrl); if (rc < 0) { smblib_err(chg, "Couldn't read TYPE_C_MODE_CFG_REG rc=%d\n", rc); - return rc; + goto unlock; } smblib_dbg(chg, PR_REGISTER, "TYPE_C_MODE_CFG_REG = 0x%02x\n", ctrl); if (ctrl & TYPEC_DISABLE_CMD_BIT) { *val = QTI_POWER_SUPPLY_TYPEC_PR_NONE; - return rc; + goto unlock; } switch (ctrl & (EN_SRC_ONLY_BIT | EN_SNK_ONLY_BIT)) { @@ -3943,10 +3945,14 @@ int smblib_get_prop_typec_power_role(struct smb_charger *chg, int *val) *val = QTI_POWER_SUPPLY_TYPEC_PR_NONE; smblib_err(chg, "unsupported power role 0x%02lx\n", ctrl & (EN_SRC_ONLY_BIT | EN_SNK_ONLY_BIT)); - return -EINVAL; + rc = -EINVAL; + goto unlock; } chg->power_role = *val; +unlock: + spin_unlock(&chg->typec_pr_lock); + return rc; } @@ -4557,6 +4563,8 @@ int smblib_set_prop_typec_power_role(struct smb_charger *chg, int val) if (chg->connector_type == QTI_POWER_SUPPLY_CONNECTOR_MICRO_USB) return 0; + spin_lock(&chg->typec_pr_lock); + smblib_dbg(chg, PR_MISC, "power role change: %d --> %d!", chg->power_role, val); @@ -4564,7 +4572,7 @@ int smblib_set_prop_typec_power_role(struct smb_charger *chg, int val) if (chg->power_role == val && chg->power_role != QTI_POWER_SUPPLY_TYPEC_PR_NONE) { smblib_dbg(chg, PR_MISC, "power role already in %d, ignore!", chg->power_role); - return 0; + goto unlock; } typec_mode = smblib_get_prop_typec_mode(chg); @@ -4590,7 +4598,6 @@ int smblib_set_prop_typec_power_role(struct smb_charger *chg, int val) smblib_dbg(chg, PR_MISC, "snk_attached = %d, src_attached = %d, is_pr_lock = %d\n", snk_attached, src_attached, is_pr_lock); cancel_delayed_work(&chg->pr_lock_clear_work); - spin_lock(&chg->typec_pr_lock); if (!chg->pr_lock_in_progress && is_pr_lock) { smblib_dbg(chg, PR_MISC, "disable type-c interrupts for power role locking\n"); smblib_typec_irq_config(chg, false); @@ -4602,7 +4609,6 @@ int smblib_set_prop_typec_power_role(struct smb_charger *chg, int val) } chg->pr_lock_in_progress = is_pr_lock; - spin_unlock(&chg->typec_pr_lock); switch (val) { case QTI_POWER_SUPPLY_TYPEC_PR_NONE: @@ -4619,7 +4625,8 @@ int smblib_set_prop_typec_power_role(struct smb_charger *chg, int val) break; default: smblib_err(chg, "power role %d not supported\n", val); - return -EINVAL; + rc = -EINVAL; + goto unlock; } rc = smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, @@ -4628,10 +4635,13 @@ int smblib_set_prop_typec_power_role(struct smb_charger *chg, int val) if (rc < 0) { smblib_err(chg, "Couldn't write 0x%02x to TYPE_C_INTRPT_ENB_SOFTWARE_CTRL rc=%d\n", power_role, rc); - return rc; + goto unlock; } chg->power_role = val; +unlock: + spin_unlock(&chg->typec_pr_lock); + return rc; }