summaryrefslogtreecommitdiff
path: root/drivers/i2c/busses/i2c-tegra.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-tegra.c')
-rw-r--r--drivers/i2c/busses/i2c-tegra.c20
1 files 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 <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/slab.h>
+
#include <asm/unaligned.h>
+#include <mach/clk.h>
+
#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)