From b9f90a825ec605b7e3c5896fb759a36ec59dec44 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 13 May 2010 19:08:32 -0700 Subject: [PATCH] [ARM] tegra: i2c: Fix i2c driver behavior on timeout/nack Change-Id: Ia0968df649fa56d93cf3522d983fde16413e854d Signed-off-by: Colin Cross --- drivers/i2c/busses/i2c-tegra.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index ae0c848c70f7..a88c8a1810d9 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -24,8 +24,11 @@ #include #include #include + #include +#include + #define TEGRA_I2C_TIMEOUT (msecs_to_jiffies(1000)) #define BYTES_PER_FIFO_WORD 4 @@ -289,6 +292,11 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) u32 val; int err = 0; + tegra_periph_reset_assert(i2c_dev->clk); + msleep(1); + tegra_periph_reset_deassert(i2c_dev->clk); + msleep(1); + clk_enable(i2c_dev->clk); dev_dbg(i2c_dev->dev, "init\n"); @@ -435,8 +443,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, dev_dbg(i2c_dev->dev, "after transfer: %08x fifo %02x\n", i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS), i2c_readl(i2c_dev, I2C_FIFO_STATUS)); if (ret == 0) { dev_err(i2c_dev->dev, "i2c transfer timed out\n"); - dev_err(i2c_dev->dev, ""); - BUG(); + tegra_i2c_init(i2c_dev); return -ETIMEDOUT; } @@ -445,7 +452,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, if (likely(i2c_dev->msg_err == I2C_ERR_NONE)) return 0; - BUG(); + tegra_i2c_init(i2c_dev); if (i2c_dev->msg_err == I2C_ERR_NO_ACK) { if (msg->flags & I2C_M_IGNORE_NAK) @@ -460,13 +467,16 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int n { struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap); int i; + int ret = 0; clk_enable(i2c_dev->clk); for (i = 0; i < num; i++) { int stop = (i == (num - 1)) ? 1 : 0; - tegra_i2c_xfer_msg(i2c_dev, &msgs[i], stop); + ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], stop); + if (ret) + break; } clk_disable(i2c_dev->clk); - return num; + return i; } static u32 tegra_i2c_func(struct i2c_adapter *adap) -- 2.34.1