summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2023-02-16 14:25:31 -0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-02-18 00:10:28 +0000
commit24453742f02c83fe21ddd7ce86d0bd52d8d35026 (patch)
treea1aaa54fc109b37d120bd4bbd71cb0c39257e5b9
parent2e22fa014469ff558aabf5016d8a9f540856ac17 (diff)
downloadchrome-ec-24453742f02c83fe21ddd7ce86d0bd52d8d35026.tar.gz
isl9241: Prevent isl9241_nvdc_to_bypass from locking control3 mutex twice
isl9241_nvdc_to_bypass locks control3 mutex and calls isl9241_get_vsys_voltage, which tries to lock the same mutex. This deadlocks whatever task calling isl9241_nvdc_to_bypass. This patch makes isl9241_nvdc_to_bypass call an internal version of isl9241_get_vsys_voltage, which skips mutex lock. BUG=b:266742386 BRANCH=None TEST=Agah Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Change-Id: I690dd0011f05f7488be6566146b7863bf747d9e6 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4261958 Reviewed-by: Jes Klinke <jbk@chromium.org> Tested-by: Jes Klinke <jbk@chromium.org>
-rw-r--r--driver/charger/isl9241.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/driver/charger/isl9241.c b/driver/charger/isl9241.c
index dd7fd243b0..b419f1ccca 100644
--- a/driver/charger/isl9241.c
+++ b/driver/charger/isl9241.c
@@ -343,18 +343,20 @@ error:
return rv;
}
-static enum ec_error_list isl9241_get_vsys_voltage(int chgnum, int port,
- int *voltage)
+/**
+ * Mutex less version of isl9241_get_vsys_voltage. This should be called only
+ * if control3_mutex_isl9241 is already locked.
+ */
+static enum ec_error_list _get_vsys_voltage(int chgnum, int port, int *voltage)
{
int val = 0;
int rv = EC_SUCCESS;
- mutex_lock(&control3_mutex_isl9241);
rv = isl9241_update(chgnum, ISL9241_REG_CONTROL3,
ISL9241_CONTROL3_ENABLE_ADC, MASK_SET);
if (rv) {
CPRINTS("Could not enable ADC for Vsys. (rv=%d)", rv);
- goto unlock_control3;
+ return rv;
}
usleep(ISL9241_ADC_POLLING_TIME_US);
@@ -365,7 +367,7 @@ static enum ec_error_list isl9241_get_vsys_voltage(int chgnum, int port,
CPRINTS("Could not read Vsys. (rv=%d)", rv);
isl9241_update(chgnum, ISL9241_REG_CONTROL3,
ISL9241_CONTROL3_ENABLE_ADC, MASK_CLR);
- goto unlock_control3;
+ return rv;
}
/* Adjust adc_val. Same as Vin. */
@@ -373,7 +375,16 @@ static enum ec_error_list isl9241_get_vsys_voltage(int chgnum, int port,
val *= ISL9241_VIN_ADC_STEP_MV;
*voltage = val;
-unlock_control3:
+ return rv;
+}
+
+static enum ec_error_list isl9241_get_vsys_voltage(int chgnum, int port,
+ int *voltage)
+{
+ int rv;
+
+ mutex_lock(&control3_mutex_isl9241);
+ rv = _get_vsys_voltage(chgnum, port, voltage);
mutex_unlock(&control3_mutex_isl9241);
return rv;
@@ -825,7 +836,7 @@ static enum ec_error_list isl9241_nvdc_to_bypass(int chgnum)
deadline.val = get_time().val + ISL9241_BYPASS_VSYS_TIMEOUT_MS * MSEC;
do {
msleep(ISL9241_BYPASS_VSYS_TIMEOUT_MS / 10);
- if (isl9241_get_vsys_voltage(chgnum, 0, &vsys)) {
+ if (_get_vsys_voltage(chgnum, 0, &vsys)) {
CPRINTS("Aborting bypass mode. Vsys is unknown.");
rv = EC_ERROR_UNKNOWN;
goto unlock_control3;