aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-tegra.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-tegra.c')
-rw-r--r--drivers/i2c/busses/i2c-tegra.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 55e5ea62ccee..8b2e555a9563 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -401,8 +401,6 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
401 disable_irq_nosync(i2c_dev->irq); 401 disable_irq_nosync(i2c_dev->irq);
402 i2c_dev->irq_disabled = 1; 402 i2c_dev->irq_disabled = 1;
403 } 403 }
404
405 complete(&i2c_dev->msg_complete);
406 goto err; 404 goto err;
407 } 405 }
408 406
@@ -411,7 +409,6 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
411 i2c_dev->msg_err |= I2C_ERR_NO_ACK; 409 i2c_dev->msg_err |= I2C_ERR_NO_ACK;
412 if (status & I2C_INT_ARBITRATION_LOST) 410 if (status & I2C_INT_ARBITRATION_LOST)
413 i2c_dev->msg_err |= I2C_ERR_ARBITRATION_LOST; 411 i2c_dev->msg_err |= I2C_ERR_ARBITRATION_LOST;
414 complete(&i2c_dev->msg_complete);
415 goto err; 412 goto err;
416 } 413 }
417 414
@@ -429,14 +426,14 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
429 tegra_i2c_mask_irq(i2c_dev, I2C_INT_TX_FIFO_DATA_REQ); 426 tegra_i2c_mask_irq(i2c_dev, I2C_INT_TX_FIFO_DATA_REQ);
430 } 427 }
431 428
429 i2c_writel(i2c_dev, status, I2C_INT_STATUS);
430 if (i2c_dev->is_dvc)
431 dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
432
432 if (status & I2C_INT_PACKET_XFER_COMPLETE) { 433 if (status & I2C_INT_PACKET_XFER_COMPLETE) {
433 BUG_ON(i2c_dev->msg_buf_remaining); 434 BUG_ON(i2c_dev->msg_buf_remaining);
434 complete(&i2c_dev->msg_complete); 435 complete(&i2c_dev->msg_complete);
435 } 436 }
436
437 i2c_writel(i2c_dev, status, I2C_INT_STATUS);
438 if (i2c_dev->is_dvc)
439 dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
440 return IRQ_HANDLED; 437 return IRQ_HANDLED;
441err: 438err:
442 /* An error occurred, mask all interrupts */ 439 /* An error occurred, mask all interrupts */
@@ -446,6 +443,8 @@ err:
446 i2c_writel(i2c_dev, status, I2C_INT_STATUS); 443 i2c_writel(i2c_dev, status, I2C_INT_STATUS);
447 if (i2c_dev->is_dvc) 444 if (i2c_dev->is_dvc)
448 dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS); 445 dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
446
447 complete(&i2c_dev->msg_complete);
449 return IRQ_HANDLED; 448 return IRQ_HANDLED;
450} 449}
451 450
@@ -476,12 +475,15 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
476 packet_header = msg->len - 1; 475 packet_header = msg->len - 1;
477 i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO); 476 i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
478 477
479 packet_header = msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT; 478 packet_header = I2C_HEADER_IE_ENABLE;
480 packet_header |= I2C_HEADER_IE_ENABLE;
481 if (!stop) 479 if (!stop)
482 packet_header |= I2C_HEADER_REPEAT_START; 480 packet_header |= I2C_HEADER_REPEAT_START;
483 if (msg->flags & I2C_M_TEN) 481 if (msg->flags & I2C_M_TEN) {
482 packet_header |= msg->addr;
484 packet_header |= I2C_HEADER_10BIT_ADDR; 483 packet_header |= I2C_HEADER_10BIT_ADDR;
484 } else {
485 packet_header |= msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT;
486 }
485 if (msg->flags & I2C_M_IGNORE_NAK) 487 if (msg->flags & I2C_M_IGNORE_NAK)
486 packet_header |= I2C_HEADER_CONT_ON_NAK; 488 packet_header |= I2C_HEADER_CONT_ON_NAK;
487 if (msg->flags & I2C_M_RD) 489 if (msg->flags & I2C_M_RD)
@@ -557,7 +559,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
557 559
558static u32 tegra_i2c_func(struct i2c_adapter *adap) 560static u32 tegra_i2c_func(struct i2c_adapter *adap)
559{ 561{
560 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 562 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
561} 563}
562 564
563static const struct i2c_algorithm tegra_i2c_algo = { 565static const struct i2c_algorithm tegra_i2c_algo = {