From: Eero Nurkkala <ext-eero.nurkkala@xxxxxxxxx> When data is read through DMA, the last element must be read separately through the RX register. It cannot be transferred by the DMA. For further details see e.g. OMAP3430 TRM. Without the fix the driver causes extra clocks to be clocked to the bus after DMA RX operations. This can cause interesting behaviour with some devices. Reported-by: Juuso Oikarinen <juuso.oikarinen@xxxxxxxxx> Signed-off-by: Juuso Oikarinen <juuso.oikarinen@xxxxxxxxx> Signed-off-by: Eero Nurkkala <ext-eero.nurkkala@xxxxxxxxx> [aaro.koskinen@xxxxxxxxx: Simplified the patch while keeping the idea.] Signed-off-by: Aaro Koskinen <aaro.koskinen@xxxxxxxxx> --- drivers/spi/omap2_mcspi.c | 21 ++++++++++++++++++++- 1 files changed, 20 insertions(+), 1 deletions(-) diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index d6d0c5d..0f640b0 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -269,7 +269,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) if (rx != NULL) { omap_set_dma_transfer_params(mcspi_dma->dma_rx_channel, - data_type, element_count, 1, + data_type, element_count - 1, 1, OMAP_DMA_SYNC_ELEMENT, mcspi_dma->dma_rx_sync_dev, 1); @@ -300,6 +300,25 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) if (rx != NULL) { wait_for_completion(&mcspi_dma->dma_rx_completion); dma_unmap_single(NULL, xfer->rx_dma, count, DMA_FROM_DEVICE); + omap2_mcspi_set_enable(spi, 0); + if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) & + OMAP2_MCSPI_CHSTAT_RXS)) { + u32 w; + + w = mcspi_read_cs_reg(spi, OMAP2_MCSPI_RX0); + if (word_len <= 8) + ((u8 *)xfer->rx_buf)[element_count - 1] = w; + else if (word_len <= 16) + ((u16 *)xfer->rx_buf)[element_count - 1] = w; + else /* word_len <= 32 */ + ((u32 *)xfer->rx_buf)[element_count - 1] = w; + } else { + dev_err(&spi->dev, "DMA RX last word empty"); + count -= (word_len <= 8) ? 1 : + (word_len <= 16) ? 2 : + /* word_len <= 32 */ 4; + } + omap2_mcspi_set_enable(spi, 1); } return count; } -- 1.5.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html