summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Osipenko <digetx@gmail.com>2020-03-24 20:12:17 +0100
committerWolfram Sang <wsa@the-dreams.de>2020-04-15 18:27:31 +0200
commit8814044fe0fa182abc9ff818d3da562de98bc9a7 (patch)
tree8d2d9ec488296900ea85f790a2c101a76b64b370 /drivers
parenti2c: tegra: Better handle case where CPU0 is busy for a long time (diff)
downloadlinux-8814044fe0fa182abc9ff818d3da562de98bc9a7.tar.xz
linux-8814044fe0fa182abc9ff818d3da562de98bc9a7.zip
i2c: tegra: Synchronize DMA before termination
DMA transfer could be completed, but CPU (which handles DMA interrupt) may get too busy and can't handle the interrupt in a timely manner, despite of DMA IRQ being raised. In this case the DMA state needs to synchronized before terminating DMA transfer in order not to miss the DMA transfer completion. Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/busses/i2c-tegra.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index a795b4e278b1..8280ac7cc1b7 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1219,6 +1219,15 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
time_left = tegra_i2c_wait_completion_timeout(
i2c_dev, &i2c_dev->dma_complete, xfer_time);
+ /*
+ * Synchronize DMA first, since dmaengine_terminate_sync()
+ * performs synchronization after the transfer's termination
+ * and we want to get a completion if transfer succeeded.
+ */
+ dmaengine_synchronize(i2c_dev->msg_read ?
+ i2c_dev->rx_dma_chan :
+ i2c_dev->tx_dma_chan);
+
dmaengine_terminate_sync(i2c_dev->msg_read ?
i2c_dev->rx_dma_chan :
i2c_dev->tx_dma_chan);