@@ -1493,6 +1493,7 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
14931493{
14941494 struct stm32f7_i2c_dev * i2c_dev = data ;
14951495 struct stm32f7_i2c_msg * f7_msg = & i2c_dev -> f7_msg ;
1496+ struct stm32_i2c_dma * dma = i2c_dev -> dma ;
14961497 void __iomem * base = i2c_dev -> base ;
14971498 u32 status , mask ;
14981499 int ret = IRQ_HANDLED ;
@@ -1518,6 +1519,10 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
15181519 dev_dbg (i2c_dev -> dev , "<%s>: Receive NACK (addr %x)\n" ,
15191520 __func__ , f7_msg -> addr );
15201521 writel_relaxed (STM32F7_I2C_ICR_NACKCF , base + STM32F7_I2C_ICR );
1522+ if (i2c_dev -> use_dma ) {
1523+ stm32f7_i2c_disable_dma_req (i2c_dev );
1524+ dmaengine_terminate_async (dma -> chan_using );
1525+ }
15211526 f7_msg -> result = - ENXIO ;
15221527 }
15231528
@@ -1533,7 +1538,7 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
15331538 /* Clear STOP flag */
15341539 writel_relaxed (STM32F7_I2C_ICR_STOPCF , base + STM32F7_I2C_ICR );
15351540
1536- if (i2c_dev -> use_dma ) {
1541+ if (i2c_dev -> use_dma && ! f7_msg -> result ) {
15371542 ret = IRQ_WAKE_THREAD ;
15381543 } else {
15391544 i2c_dev -> master_mode = false;
@@ -1546,7 +1551,7 @@ static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
15461551 if (f7_msg -> stop ) {
15471552 mask = STM32F7_I2C_CR2_STOP ;
15481553 stm32f7_i2c_set_bits (base + STM32F7_I2C_CR2 , mask );
1549- } else if (i2c_dev -> use_dma ) {
1554+ } else if (i2c_dev -> use_dma && ! f7_msg -> result ) {
15501555 ret = IRQ_WAKE_THREAD ;
15511556 } else if (f7_msg -> smbus ) {
15521557 stm32f7_i2c_smbus_rep_start (i2c_dev );
@@ -1583,7 +1588,7 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
15831588 if (!ret ) {
15841589 dev_dbg (i2c_dev -> dev , "<%s>: Timed out\n" , __func__ );
15851590 stm32f7_i2c_disable_dma_req (i2c_dev );
1586- dmaengine_terminate_all (dma -> chan_using );
1591+ dmaengine_terminate_async (dma -> chan_using );
15871592 f7_msg -> result = - ETIMEDOUT ;
15881593 }
15891594
@@ -1660,7 +1665,7 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data)
16601665 /* Disable dma */
16611666 if (i2c_dev -> use_dma ) {
16621667 stm32f7_i2c_disable_dma_req (i2c_dev );
1663- dmaengine_terminate_all (dma -> chan_using );
1668+ dmaengine_terminate_async (dma -> chan_using );
16641669 }
16651670
16661671 i2c_dev -> master_mode = false;
@@ -1696,12 +1701,26 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap,
16961701 time_left = wait_for_completion_timeout (& i2c_dev -> complete ,
16971702 i2c_dev -> adap .timeout );
16981703 ret = f7_msg -> result ;
1704+ if (ret ) {
1705+ if (i2c_dev -> use_dma )
1706+ dmaengine_synchronize (dma -> chan_using );
1707+
1708+ /*
1709+ * It is possible that some unsent data have already been
1710+ * written into TXDR. To avoid sending old data in a
1711+ * further transfer, flush TXDR in case of any error
1712+ */
1713+ writel_relaxed (STM32F7_I2C_ISR_TXE ,
1714+ i2c_dev -> base + STM32F7_I2C_ISR );
1715+ goto pm_free ;
1716+ }
16991717
17001718 if (!time_left ) {
17011719 dev_dbg (i2c_dev -> dev , "Access to slave 0x%x timed out\n" ,
17021720 i2c_dev -> msg -> addr );
17031721 if (i2c_dev -> use_dma )
1704- dmaengine_terminate_all (dma -> chan_using );
1722+ dmaengine_terminate_sync (dma -> chan_using );
1723+ stm32f7_i2c_wait_free_bus (i2c_dev );
17051724 ret = - ETIMEDOUT ;
17061725 }
17071726
@@ -1744,13 +1763,25 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
17441763 timeout = wait_for_completion_timeout (& i2c_dev -> complete ,
17451764 i2c_dev -> adap .timeout );
17461765 ret = f7_msg -> result ;
1747- if (ret )
1766+ if (ret ) {
1767+ if (i2c_dev -> use_dma )
1768+ dmaengine_synchronize (dma -> chan_using );
1769+
1770+ /*
1771+ * It is possible that some unsent data have already been
1772+ * written into TXDR. To avoid sending old data in a
1773+ * further transfer, flush TXDR in case of any error
1774+ */
1775+ writel_relaxed (STM32F7_I2C_ISR_TXE ,
1776+ i2c_dev -> base + STM32F7_I2C_ISR );
17481777 goto pm_free ;
1778+ }
17491779
17501780 if (!timeout ) {
17511781 dev_dbg (dev , "Access to slave 0x%x timed out\n" , f7_msg -> addr );
17521782 if (i2c_dev -> use_dma )
1753- dmaengine_terminate_all (dma -> chan_using );
1783+ dmaengine_terminate_sync (dma -> chan_using );
1784+ stm32f7_i2c_wait_free_bus (i2c_dev );
17541785 ret = - ETIMEDOUT ;
17551786 goto pm_free ;
17561787 }
0 commit comments