From 3e5f29bd22e597d66d9c1013a0ab190e6b48a8ba Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Mon, 7 May 2012 12:16:19 +0530 Subject: i2c: tegra: notify transfer-complete after clearing status. commit c889e91d2cc22123f20f40dde0c0a91856a20eea upstream. The notification of the transfer complete by calling complete() should be done after clearing all interrupt status. This avoids the race condition of misconfigure the i2c controller in multi-core environment. Signed-off-by: Laxman Dewangan Acked-by: Stephen Warren Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-tegra.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/i2c') diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 55e5ea62ccee..df19f3d588cd 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) disable_irq_nosync(i2c_dev->irq); i2c_dev->irq_disabled = 1; } - - complete(&i2c_dev->msg_complete); goto err; } @@ -411,7 +409,6 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id) i2c_dev->msg_err |= I2C_ERR_NO_ACK; if (status & I2C_INT_ARBITRATION_LOST) i2c_dev->msg_err |= I2C_ERR_ARBITRATION_LOST; - complete(&i2c_dev->msg_complete); goto err; } @@ -429,14 +426,14 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id) tegra_i2c_mask_irq(i2c_dev, I2C_INT_TX_FIFO_DATA_REQ); } + i2c_writel(i2c_dev, status, I2C_INT_STATUS); + if (i2c_dev->is_dvc) + dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS); + if (status & I2C_INT_PACKET_XFER_COMPLETE) { BUG_ON(i2c_dev->msg_buf_remaining); complete(&i2c_dev->msg_complete); } - - i2c_writel(i2c_dev, status, I2C_INT_STATUS); - if (i2c_dev->is_dvc) - dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS); return IRQ_HANDLED; err: /* An error occurred, mask all interrupts */ @@ -446,6 +443,8 @@ err: i2c_writel(i2c_dev, status, I2C_INT_STATUS); if (i2c_dev->is_dvc) dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS); + + complete(&i2c_dev->msg_complete); return IRQ_HANDLED; } -- cgit v1.2.3