summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2012-08-22 13:43:08 +0530
committerSimone Willett <swillett@nvidia.com>2012-08-22 12:05:25 -0700
commitf13284fab49d2ca544fda157ba8006ab1004cc1a (patch)
treed493b19724cb81cb414e14ce327acb1657605c08 /drivers
parent064618cb59271bf674f489219028807ff712b241 (diff)
i2c: tegra: Add delay before resetting the controller after NACK
NACK interrupt is generated before I2C controller generates the STOP condition on bus. Because of this reset of controller is happening before I2C controller could complete STOP condition. So wait for some time before resetting the controller so that STOP condition has delivered properly on bus. Added delay of 2 clock period before resetting the controller in case of NACK error. Signed-off-by: Alok Chauhan <alokc@nvidia.com> Acked-by: Stephen Warren <swarren@wwwdotorg.org> Taken change from mainline commit. Change-Id: Id089aae313614e58ec6da36eda4ff2d87c5cddc3 Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-on: http://git-master/r/125148 Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/busses/i2c-tegra.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 2597db6a0c37..2c795592f80e 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -479,10 +479,6 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
tegra_i2c_clock_enable(i2c_dev);
- /* Interrupt generated before sending stop signal so
- * wait for some time so that stop signal can be send proerly */
- mdelay(1);
-
tegra_periph_reset_assert(i2c_dev->div_clk);
udelay(2);
tegra_periph_reset_deassert(i2c_dev->div_clk);
@@ -760,6 +756,14 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_bus *i2c_bus,
}
}
+ /*
+ * NACK interrupt is generated before the I2C controller generates the
+ * STOP condition on the bus. So wait for 2 clock periods before resetting
+ * the controller so that STOP condition has been delivered properly.
+ */
+ if (i2c_dev->msg_err == I2C_ERR_NO_ACK)
+ udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->last_bus_clk_rate));
+
tegra_i2c_init(i2c_dev);
if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {