mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
spi: dw: don't immediately kill DMA transfers if an error occurs
Disabling the peripheral resets controller state which has a dangerous side-effect of disabling the DMA handshake interface while it is active. This can cause DMA channels to hang. The error recovery pathway will wait for DMA to stop and reset the chip anyway, so mask further FIFO interrupts and let the transfer finish gracefully. Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
This commit is contained in:
committed by
Dom Cobley
parent
5c9c12bacb
commit
1ed0c240a3
@@ -202,7 +202,18 @@ int dw_spi_check_status(struct dw_spi *dws, bool raw)
|
||||
|
||||
/* Generically handle the erroneous situation */
|
||||
if (ret) {
|
||||
dw_spi_reset_chip(dws);
|
||||
/*
|
||||
* Forcibly halting the controller can cause DMA to hang.
|
||||
* Defer to dw_spi_handle_err outside of interrupt context
|
||||
* and mask further interrupts for the current transfer.
|
||||
*/
|
||||
if (dws->dma_mapped) {
|
||||
dw_spi_mask_intr(dws, 0xff);
|
||||
dw_readl(dws, DW_SPI_ICR);
|
||||
} else {
|
||||
dw_spi_reset_chip(dws);
|
||||
}
|
||||
|
||||
if (dws->host->cur_msg)
|
||||
dws->host->cur_msg->status = ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user