diff options
-rw-r--r-- | drivers/i2c/busses/i2c-designware.c | 26 |
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 | */ |
358 | static void | 366 | static void |
359 | i2c_dw_xfer_msg(struct dw_i2c_dev *dev) | 367 | i2c_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; |