Re: [PATCH 1/6] i2c: davinci: Fix smbus Oops with AIC33 usage

Previous thread: by Kevin Hilman on Tuesday, April 6, 2010 - 10:42 am. (1 message)

Next thread: by Kevin Hilman on Tuesday, April 6, 2010 - 10:42 am. (1 message)
From: Kevin Hilman
Subject:
Date: Tuesday, April 6, 2010 - 10:42 am

From: Dirk Behme <dirk.behme@googlemail.com>

This fixes Oops at kernel startup while "scanning" for TLV320AIC23IDx
addresses.

Additional fix from Sudhakar Rajashekhara: I think 'first byte set'
should come after the write because an I2C transaction is being
carried out before configuring the I2C mode register (which has bits
to configure Master, Start condition etc), which causes undefined
behavior.

Signed-off-by: Sudhakar Rajashekhara <sudhakar.raj@ti.com>
Signed-off-by: Alexander Vasiliev <alexvasiljev@gmail.com>
Signed-off-by: Brad Griffis <bgriffis@ti.com>
Signed-off-by: Dirk Behme <dirk.behme@gmail.com>
Acked-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 drivers/i2c/busses/i2c-davinci.c |   31 +++++++++++++++++++++++++++----
 1 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index c89687a..3b9ab23 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -112,6 +112,7 @@ struct davinci_i2c_dev {
 	u8			*buf;
 	size_t			buf_len;
 	int			irq;
+	int			stop;
 	u8			terminate;
 	struct i2c_adapter	adapter;
 };
@@ -249,9 +250,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
 	u16 w;
 	int r;
 
-	if (msg->len == 0)
-		return -EINVAL;
-
 	if (!pdata)
 		pdata = &davinci_i2c_platform_data_default;
 	/* Introduce a delay, required for some boards (e.g Davinci EVM) */
@@ -263,6 +261,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
 
 	dev->buf = msg->buf;
 	dev->buf_len = msg->len;
+	dev->stop = stop;
 
 	davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len);
 
@@ -280,6 +279,10 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
 		flag |= DAVINCI_I2C_MDR_TRX;
 	if (stop)
 		flag |= DAVINCI_I2C_MDR_STP;
+	if (msg->len == 0) {
+		flag |= DAVINCI_I2C_MDR_RM;
+		flag &= ~DAVINCI_I2C_MDR_STP;
+	}
 
 	/* Enable receive or transmit ...
From: Ben Dooks
Date: Monday, April 19, 2010 - 5:05 pm

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'
--

Previous thread: by Kevin Hilman on Tuesday, April 6, 2010 - 10:42 am. (1 message)

Next thread: by Kevin Hilman on Tuesday, April 6, 2010 - 10:42 am. (1 message)