Skip to content

Commit 31b90a9

Browse files
Alain Volmatwsakernel
authored andcommitted
i2c: stm32f7: stop dma transfer in case of NACK
In case of receiving a NACK, the dma transfer should be stopped to avoid feeding data into the FIFO. Also ensure to properly return the proper error code and avoid waiting for the end of the dma completion in case of error happening during the transmission. Fixes: 7ecc8cf ("i2c: i2c-stm32f7: Add DMA support") Signed-off-by: Alain Volmat <[email protected]> Reviewed-by: Pierre-Yves MORDRET <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent b933d1f commit 31b90a9

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

drivers/i2c/busses/i2c-stm32f7.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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_all(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);

0 commit comments

Comments
 (0)