aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-davinci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-davinci.c')
-rw-r--r--drivers/i2c/busses/i2c-davinci.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 2222c87876b9..5795c8398c7c 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -331,21 +331,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
331 INIT_COMPLETION(dev->cmd_complete); 331 INIT_COMPLETION(dev->cmd_complete);
332 dev->cmd_err = 0; 332 dev->cmd_err = 0;
333 333
334 /* Take I2C out of reset, configure it as master and set the 334 /* Take I2C out of reset and configure it as master */
335 * start bit */ 335 flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST;
336 flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST | DAVINCI_I2C_MDR_STT;
337 336
338 /* if the slave address is ten bit address, enable XA bit */ 337 /* if the slave address is ten bit address, enable XA bit */
339 if (msg->flags & I2C_M_TEN) 338 if (msg->flags & I2C_M_TEN)
340 flag |= DAVINCI_I2C_MDR_XA; 339 flag |= DAVINCI_I2C_MDR_XA;
341 if (!(msg->flags & I2C_M_RD)) 340 if (!(msg->flags & I2C_M_RD))
342 flag |= DAVINCI_I2C_MDR_TRX; 341 flag |= DAVINCI_I2C_MDR_TRX;
343 if (stop) 342 if (msg->len == 0)
344 flag |= DAVINCI_I2C_MDR_STP;
345 if (msg->len == 0) {
346 flag |= DAVINCI_I2C_MDR_RM; 343 flag |= DAVINCI_I2C_MDR_RM;
347 flag &= ~DAVINCI_I2C_MDR_STP;
348 }
349 344
350 /* Enable receive or transmit interrupts */ 345 /* Enable receive or transmit interrupts */
351 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); 346 w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
@@ -357,7 +352,11 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
357 352
358 dev->terminate = 0; 353 dev->terminate = 0;
359 354
360 /* write the data into mode register */ 355 /*
356 * Write mode register first as needed for correct behaviour
357 * on OMAP-L138, but don't set STT yet to avoid a race with XRDY
358 * occuring before we have loaded DXR
359 */
361 davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); 360 davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
362 361
363 /* 362 /*
@@ -365,12 +364,19 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
365 * because transmit-data-ready interrupt can come before 364 * because transmit-data-ready interrupt can come before
366 * NACK-interrupt during sending of previous message and 365 * NACK-interrupt during sending of previous message and
367 * ICDXR may have wrong data 366 * ICDXR may have wrong data
367 * It also saves us one interrupt, slightly faster
368 */ 368 */
369 if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { 369 if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) {
370 davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); 370 davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++);
371 dev->buf_len--; 371 dev->buf_len--;
372 } 372 }
373 373
374 /* Set STT to begin transmit now DXR is loaded */
375 flag |= DAVINCI_I2C_MDR_STT;
376 if (stop && msg->len != 0)
377 flag |= DAVINCI_I2C_MDR_STP;
378 davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
379
374 r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, 380 r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
375 dev->adapter.timeout); 381 dev->adapter.timeout);
376 if (r == 0) { 382 if (r == 0) {