We only freed the bounce buffer after successful DMA, missing the cases
where DMA setup may have gone wrong. Use a better location which always
gets called after each message and use 'stop_after_dma' as a flag for a
successful transfer.

Signed-off-by: Wolfram Sang <wsa+rene...@sang-engineering.com>
---
 drivers/i2c/busses/i2c-sh_mobile.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-sh_mobile.c 
b/drivers/i2c/busses/i2c-sh_mobile.c
index 456581e3c1d2..c56a86da958e 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -515,8 +515,6 @@ static void sh_mobile_i2c_dma_callback(void *data)
        pd->pos = pd->msg->len;
        pd->stop_after_dma = true;
 
-       i2c_put_dma_safe_msg_buf(pd->dma_buf, pd->msg, true);
-
        iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE);
 }
 
@@ -714,6 +712,10 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
                timeout = wait_event_timeout(pd->wait,
                                       pd->sr & (ICSR_TACK | SW_DONE),
                                       adapter->timeout);
+
+               /* 'stop_after_dma' tells if DMA transfer was complete */
+               i2c_put_dma_safe_msg_buf(pd->dma_buf, pd->msg, 
pd->stop_after_dma);
+
                if (!timeout) {
                        dev_err(pd->dev, "Transfer request timed out\n");
                        if (pd->dma_direction != DMA_NONE)
-- 
2.11.0

Reply via email to