summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
authorHarry Yang <harryy@codeaurora.org>2016-10-26 00:32:51 -0700
committerAbhijeet Dharmapurikar <adharmap@codeaurora.org>2017-01-17 20:30:24 -0800
commitc079a27b7355a2cff2b9148adf581eaedd2989fe (patch)
tree3745e5374e287c36862ba46bf7bec50ae25ae0d7 /drivers/mfd
parent37c5f804a2e32623ddbe51e68c527bae7be81582 (diff)
mfd: qcom-i2c-pmic: Add retry mechanism for slow slave responding
In some devices, qcom-i2c-pmic driver fails probe from the initial poke failure of attached SEM slave. As software workaround, this issue can be recovered by retrying to ensure the unresponsive device is powered. CRs-Fixed: 1083672 Change-Id: Ie828ba236f42b24a3d2acefdf069445cc72503f1 Signed-off-by: Harry Yang <harryy@codeaurora.org> Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/qcom-i2c-pmic.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/mfd/qcom-i2c-pmic.c b/drivers/mfd/qcom-i2c-pmic.c
index ea5ac972b096..590e4c1a3f52 100644
--- a/drivers/mfd/qcom-i2c-pmic.c
+++ b/drivers/mfd/qcom-i2c-pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -467,12 +467,29 @@ static int i2c_pmic_parse_dt(struct i2c_pmic *chip)
return rc;
}
+#define MAX_I2C_RETRIES 3
+static int i2c_pmic_read(struct regmap *map, unsigned int reg, void *val,
+ size_t val_count)
+{
+ int rc, retries = 0;
+
+ do {
+ rc = regmap_bulk_read(map, reg, val, val_count);
+ } while (rc == -ENOTCONN && retries++ < MAX_I2C_RETRIES);
+
+ if (retries > 1)
+ pr_err("i2c_pmic_read failed for %d retries, rc = %d\n",
+ retries - 1, rc);
+
+ return rc;
+}
+
static int i2c_pmic_determine_initial_status(struct i2c_pmic *chip)
{
int rc, i;
for (i = 0; i < chip->num_periphs; i++) {
- rc = regmap_bulk_read(chip->regmap,
+ rc = i2c_pmic_read(chip->regmap,
chip->periph[i].addr | INT_SET_TYPE_OFFSET,
chip->periph[i].cached, IRQ_MAX_REGS);
if (rc < 0) {