]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
i2c: tegra: Synchronize DMA before termination
authorDmitry Osipenko <digetx@gmail.com>
Tue, 24 Mar 2020 19:12:17 +0000 (22:12 +0300)
committerThierry Reding <treding@nvidia.com>
Fri, 8 May 2020 10:42:33 +0000 (12:42 +0200)
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: Thierry Reding <treding@nvidia.com>
drivers/i2c/busses/i2c-tegra.c

index 9232038ccb40c11ba2f27c15efc231c61ff1ba6b..7c92e91a1cc25466017389b2a1a731aade69aecf 100644 (file)
@@ -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);