diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2023-02-16 14:25:31 -0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-02-18 00:10:28 +0000 |
commit | 24453742f02c83fe21ddd7ce86d0bd52d8d35026 (patch) | |
tree | a1aaa54fc109b37d120bd4bbd71cb0c39257e5b9 | |
parent | 2e22fa014469ff558aabf5016d8a9f540856ac17 (diff) | |
download | chrome-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.c | 25 |
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; |