@@ -514,6 +514,12 @@ static irqreturn_t stm32_spi_irq(int irq, void *dev_id)
dev_warn(spi->dev, "Communication suspended\n");
if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
stm32_spi_read_rxfifo(spi, false);
+ /*
+ * If communication is suspended while using DMA, it means
+ * that something went wrong, so stop the current transfer
+ */
+ if (spi->cur_usedma)
+ end = true;
}
if (sr & SPI_SR_MODF) {
@@ -525,6 +531,12 @@ static irqreturn_t stm32_spi_irq(int irq, void *dev_id)
dev_warn(spi->dev, "Overrun: received value discarded\n");
if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
stm32_spi_read_rxfifo(spi, false);
+ /*
+ * If overrun is detected while using DMA, it means that
+ * something went wrong, so stop the current transfer
+ */
+ if (spi->cur_usedma)
+ end = true;
}
if (sr & SPI_SR_EOT) {
@@ -645,12 +657,10 @@ static void stm32_spi_dma_cb(void *data)
spin_unlock_irqrestore(&spi->lock, flags);
- if (!(sr & SPI_SR_EOT)) {
- dev_warn(spi->dev, "DMA callback (sr=0x%08x)\n", sr);
+ if (!(sr & SPI_SR_EOT))
+ dev_warn(spi->dev, "DMA error (sr=0x%08x)\n", sr);
- spi_finalize_current_transfer(spi->master);
- stm32_spi_disable(spi);
- }
+ /* Now wait for EOT, or SUSP or OVR in case of error */
}
/**
@@ -986,7 +996,8 @@ static int stm32_spi_transfer_one(struct spi_master *master,
spi->tx_len = spi->tx_buf ? transfer->len : 0;
spi->rx_len = spi->rx_buf ? transfer->len : 0;
- spi->cur_usedma = stm32_spi_can_dma(master, spi_dev, transfer);
+ spi->cur_usedma = (master->can_dma &&
+ stm32_spi_can_dma(master, spi_dev, transfer));
ret = stm32_spi_transfer_one_setup(spi, spi_dev, transfer);
if (ret) {