aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-mxs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-mxs.c')
-rw-r--r--drivers/i2c/busses/i2c-mxs.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 0ec1f1502def..c67d89fc6254 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -56,6 +56,7 @@
56#define MXS_I2C_CTRL1_SET (0x44) 56#define MXS_I2C_CTRL1_SET (0x44)
57#define MXS_I2C_CTRL1_CLR (0x48) 57#define MXS_I2C_CTRL1_CLR (0x48)
58 58
59#define MXS_I2C_CTRL1_CLR_GOT_A_NAK 0x10000000
59#define MXS_I2C_CTRL1_BUS_FREE_IRQ 0x80 60#define MXS_I2C_CTRL1_BUS_FREE_IRQ 0x80
60#define MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ 0x40 61#define MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ 0x40
61#define MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ 0x20 62#define MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ 0x20
@@ -340,6 +341,23 @@ static int mxs_i2c_pio_wait_cplt(struct mxs_i2c_dev *i2c, int last)
340 return 0; 341 return 0;
341} 342}
342 343
344static int mxs_i2c_pio_check_error_state(struct mxs_i2c_dev *i2c)
345{
346 u32 state;
347
348 state = readl(i2c->regs + MXS_I2C_CTRL1_CLR) & MXS_I2C_IRQ_MASK;
349
350 if (state & MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ)
351 i2c->cmd_err = -ENXIO;
352 else if (state & (MXS_I2C_CTRL1_EARLY_TERM_IRQ |
353 MXS_I2C_CTRL1_MASTER_LOSS_IRQ |
354 MXS_I2C_CTRL1_SLAVE_STOP_IRQ |
355 MXS_I2C_CTRL1_SLAVE_IRQ))
356 i2c->cmd_err = -EIO;
357
358 return i2c->cmd_err;
359}
360
343static void mxs_i2c_pio_trigger_cmd(struct mxs_i2c_dev *i2c, u32 cmd) 361static void mxs_i2c_pio_trigger_cmd(struct mxs_i2c_dev *i2c, u32 cmd)
344{ 362{
345 u32 reg; 363 u32 reg;
@@ -380,6 +398,9 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,
380 if (ret) 398 if (ret)
381 return ret; 399 return ret;
382 400
401 if (mxs_i2c_pio_check_error_state(i2c))
402 goto cleanup;
403
383 /* READ command. */ 404 /* READ command. */
384 mxs_i2c_pio_trigger_cmd(i2c, 405 mxs_i2c_pio_trigger_cmd(i2c,
385 MXS_CMD_I2C_READ | flags | 406 MXS_CMD_I2C_READ | flags |
@@ -440,6 +461,10 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,
440 if (ret) 461 if (ret)
441 return ret; 462 return ret;
442 463
464 /* make sure we capture any occurred error into cmd_err */
465 mxs_i2c_pio_check_error_state(i2c);
466
467cleanup:
443 /* Clear any dangling IRQs and re-enable interrupts. */ 468 /* Clear any dangling IRQs and re-enable interrupts. */
444 writel(MXS_I2C_IRQ_MASK, i2c->regs + MXS_I2C_CTRL1_CLR); 469 writel(MXS_I2C_IRQ_MASK, i2c->regs + MXS_I2C_CTRL1_CLR);
445 writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET); 470 writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
@@ -471,12 +496,12 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
471 * using PIO mode while longer transfers use DMA. The 8 byte border is 496 * using PIO mode while longer transfers use DMA. The 8 byte border is
472 * based on this empirical measurement and a lot of previous frobbing. 497 * based on this empirical measurement and a lot of previous frobbing.
473 */ 498 */
499 i2c->cmd_err = 0;
474 if (msg->len < 8) { 500 if (msg->len < 8) {
475 ret = mxs_i2c_pio_setup_xfer(adap, msg, flags); 501 ret = mxs_i2c_pio_setup_xfer(adap, msg, flags);
476 if (ret) 502 if (ret)
477 mxs_i2c_reset(i2c); 503 mxs_i2c_reset(i2c);
478 } else { 504 } else {
479 i2c->cmd_err = 0;
480 INIT_COMPLETION(i2c->cmd_complete); 505 INIT_COMPLETION(i2c->cmd_complete);
481 ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); 506 ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
482 if (ret) 507 if (ret)
@@ -486,13 +511,19 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
486 msecs_to_jiffies(1000)); 511 msecs_to_jiffies(1000));
487 if (ret == 0) 512 if (ret == 0)
488 goto timeout; 513 goto timeout;
514 }
489 515
490 if (i2c->cmd_err == -ENXIO) 516 if (i2c->cmd_err == -ENXIO) {
491 mxs_i2c_reset(i2c); 517 /*
492 518 * If the transfer fails with a NAK from the slave the
493 ret = i2c->cmd_err; 519 * controller halts until it gets told to return to idle state.
520 */
521 writel(MXS_I2C_CTRL1_CLR_GOT_A_NAK,
522 i2c->regs + MXS_I2C_CTRL1_SET);
494 } 523 }
495 524
525 ret = i2c->cmd_err;
526
496 dev_dbg(i2c->dev, "Done with err=%d\n", ret); 527 dev_dbg(i2c->dev, "Done with err=%d\n", ret);
497 528
498 return ret; 529 return ret;