aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-mxs.c
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2013-04-14 20:16:55 -0400
committerWolfram Sang <wsa@the-dreams.de>2013-04-15 12:29:58 -0400
commit92b775c2949287e675fdb3cac96bb0cda64efbfe (patch)
tree2e7d17202e52335379e4f2d27e7c147dc2c81fe8 /drivers/i2c/busses/i2c-mxs.c
parent535ebd217d38dde481a927f21e6824d8b37bdb28 (diff)
i2c: mxs: do error checking and handling in PIO mode
In PIO mode we can end up with the same errors as in DMA mode, but as IRQs are disabled there we have to check for them manually after each command. Also don't use the big controller reset hammer when receiving a NAK from a slave. It's sufficient to tell the controller to continue at a clean state. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Tested-by: Marek Vasut <marex@denx.de> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
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;