Commit 28d98666 authored by Dmitry Osipenko's avatar Dmitry Osipenko Committed by Wolfram Sang
Browse files

i2c: tegra: Always terminate DMA transfer



It is possible that I2C could error out in the middle of DMA transfer and
in this case DMA channel needs to be reset, otherwise a follow up transfer
will fail because DMA channel stays blocked.

Tested-by: default avatarThierry Reding <treding@nvidia.com>
Signed-off-by: default avatarDmitry Osipenko <digetx@gmail.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 4211ffc3
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -1220,11 +1220,12 @@ 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);

		if (time_left == 0) {
			dev_err(i2c_dev->dev, "DMA transfer timeout\n");
		dmaengine_terminate_sync(i2c_dev->msg_read ?
					 i2c_dev->rx_dma_chan :
					 i2c_dev->tx_dma_chan);

		if (time_left == 0) {
			dev_err(i2c_dev->dev, "DMA transfer timeout\n");
			tegra_i2c_init(i2c_dev, true);
			return -ETIMEDOUT;
		}
@@ -1237,11 +1238,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
			memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf,
			       msg->len);
		}

		if (i2c_dev->msg_err != I2C_ERR_NONE)
			dmaengine_synchronize(i2c_dev->msg_read ?
					      i2c_dev->rx_dma_chan :
					      i2c_dev->tx_dma_chan);
	}

	time_left = tegra_i2c_wait_completion_timeout(