aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/busses/i2c-designware.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-designware.c b/drivers/i2c/busses/i2c-designware.c
index 5a3bd74c81d5..f184d822d3d4 100644
--- a/drivers/i2c/busses/i2c-designware.c
+++ b/drivers/i2c/busses/i2c-designware.c
@@ -90,6 +90,11 @@
90#define DW_IC_INTR_START_DET 0x400 90#define DW_IC_INTR_START_DET 0x400
91#define DW_IC_INTR_GEN_CALL 0x800 91#define DW_IC_INTR_GEN_CALL 0x800
92 92
93#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
94 DW_IC_INTR_TX_EMPTY | \
95 DW_IC_INTR_TX_ABRT | \
96 DW_IC_INTR_STOP_DET)
97
93#define DW_IC_STATUS_ACTIVITY 0x1 98#define DW_IC_STATUS_ACTIVITY 0x1
94 99
95#define DW_IC_ERR_TX_ABRT 0x1 100#define DW_IC_ERR_TX_ABRT 0x1
@@ -347,13 +352,16 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
347 352
348 /* Enable the adapter */ 353 /* Enable the adapter */
349 writel(1, dev->base + DW_IC_ENABLE); 354 writel(1, dev->base + DW_IC_ENABLE);
355
356 /* Enable interrupts */
357 writel(DW_IC_INTR_DEFAULT_MASK, dev->base + DW_IC_INTR_MASK);
350} 358}
351 359
352/* 360/*
353 * Initiate low level master read/write transaction. 361 * Initiate (and continue) low level master read/write transaction.
354 * This function is called from i2c_dw_xfer when starting a transfer. 362 * This function is only called from i2c_dw_isr, and pumping i2c_msg
355 * This function is also called from i2c_dw_isr to continue a transfer 363 * messages into the tx buffer. Even if the size of i2c_msg data is
356 * that is longer than the size of the TX FIFO. 364 * longer than the size of the tx buffer, it handles everything.
357 */ 365 */
358static void 366static void
359i2c_dw_xfer_msg(struct dw_i2c_dev *dev) 367i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
@@ -365,7 +373,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
365 u32 buf_len = dev->tx_buf_len; 373 u32 buf_len = dev->tx_buf_len;
366 u8 *buf = dev->tx_buf;; 374 u8 *buf = dev->tx_buf;;
367 375
368 intr_mask = DW_IC_INTR_STOP_DET | DW_IC_INTR_TX_ABRT | DW_IC_INTR_RX_FULL; 376 intr_mask = DW_IC_INTR_DEFAULT_MASK;
369 377
370 for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) { 378 for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) {
371 /* if target address has changed, we need to 379 /* if target address has changed, we need to
@@ -405,11 +413,12 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
405 413
406 if (buf_len > 0) { 414 if (buf_len > 0) {
407 /* more bytes to be written */ 415 /* more bytes to be written */
408 intr_mask |= DW_IC_INTR_TX_EMPTY;
409 dev->status |= STATUS_WRITE_IN_PROGRESS; 416 dev->status |= STATUS_WRITE_IN_PROGRESS;
410 break; 417 break;
411 } else 418 } else {
412 dev->status &= ~STATUS_WRITE_IN_PROGRESS; 419 dev->status &= ~STATUS_WRITE_IN_PROGRESS;
420 intr_mask &= ~DW_IC_INTR_TX_EMPTY;
421 }
413 } 422 }
414 423
415 writel(intr_mask, dev->base + DW_IC_INTR_MASK); 424 writel(intr_mask, dev->base + DW_IC_INTR_MASK);
@@ -479,7 +488,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
479 488
480 /* start the transfers */ 489 /* start the transfers */
481 i2c_dw_xfer_init(dev); 490 i2c_dw_xfer_init(dev);
482 i2c_dw_xfer_msg(dev);
483 491
484 /* wait for tx to complete */ 492 /* wait for tx to complete */
485 ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ); 493 ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ);
@@ -687,7 +695,7 @@ static int __devinit dw_i2c_probe(struct platform_device *pdev)
687 i2c_dw_init(dev); 695 i2c_dw_init(dev);
688 696
689 writel(0, dev->base + DW_IC_INTR_MASK); /* disable IRQ */ 697 writel(0, dev->base + DW_IC_INTR_MASK); /* disable IRQ */
690 r = request_irq(dev->irq, i2c_dw_isr, 0, pdev->name, dev); 698 r = request_irq(dev->irq, i2c_dw_isr, IRQF_DISABLED, pdev->name, dev);
691 if (r) { 699 if (r) {
692 dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); 700 dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
693 goto err_iounmap; 701 goto err_iounmap;