From c079a27b7355a2cff2b9148adf581eaedd2989fe Mon Sep 17 00:00:00 2001 From: Harry Yang Date: Wed, 26 Oct 2016 00:32:51 -0700 Subject: [PATCH] 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 Signed-off-by: Abhijeet Dharmapurikar --- drivers/mfd/qcom-i2c-pmic.c | 21 +++++++++++++++++++-- 1 file 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) {