Skip to content

Commit 2764c50

Browse files
Ilkka Koskinenglikely
authored andcommitted
spi/omap2_mcspi: Verify TX reg is empty after TX only xfer with DMA
In case of TX only with DMA, the driver assumes that the data has been transferred once DMA callback in invoked. However, SPI's shift register may still contain data. Thus, the driver is supposed to verify that the register is empty and the end of the SPI transfer has been reached. Signed-off-by: Ilkka Koskinen <[email protected]> Tested-by: Tuomas Katila <[email protected]> Acked-by: Tony Lindgren <[email protected]> Signed-off-by: Grant Likely <[email protected]>
1 parent e1993ed commit 2764c50

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

drivers/spi/omap2_mcspi.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,19 @@ static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)
296296
return 0;
297297
}
298298

299+
static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)
300+
{
301+
unsigned long timeout;
302+
303+
timeout = jiffies + msecs_to_jiffies(1000);
304+
while (!(__raw_readl(reg) & bit)) {
305+
if (time_after(jiffies, timeout))
306+
return -1;
307+
cpu_relax();
308+
}
309+
return 0;
310+
}
311+
299312
static unsigned
300313
omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
301314
{
@@ -309,11 +322,14 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
309322
u32 l;
310323
u8 * rx;
311324
const u8 * tx;
325+
void __iomem *chstat_reg;
312326

313327
mcspi = spi_master_get_devdata(spi->master);
314328
mcspi_dma = &mcspi->dma_channels[spi->chip_select];
315329
l = mcspi_cached_chconf0(spi);
316330

331+
chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
332+
317333
count = xfer->len;
318334
c = count;
319335
word_len = cs->word_len;
@@ -382,6 +398,16 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
382398
if (tx != NULL) {
383399
wait_for_completion(&mcspi_dma->dma_tx_completion);
384400
dma_unmap_single(NULL, xfer->tx_dma, count, DMA_TO_DEVICE);
401+
402+
/* for TX_ONLY mode, be sure all words have shifted out */
403+
if (rx == NULL) {
404+
if (mcspi_wait_for_reg_bit(chstat_reg,
405+
OMAP2_MCSPI_CHSTAT_TXS) < 0)
406+
dev_err(&spi->dev, "TXS timed out\n");
407+
else if (mcspi_wait_for_reg_bit(chstat_reg,
408+
OMAP2_MCSPI_CHSTAT_EOT) < 0)
409+
dev_err(&spi->dev, "EOT timed out\n");
410+
}
385411
}
386412

387413
if (rx != NULL) {
@@ -435,19 +461,6 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
435461
return count;
436462
}
437463

438-
static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)
439-
{
440-
unsigned long timeout;
441-
442-
timeout = jiffies + msecs_to_jiffies(1000);
443-
while (!(__raw_readl(reg) & bit)) {
444-
if (time_after(jiffies, timeout))
445-
return -1;
446-
cpu_relax();
447-
}
448-
return 0;
449-
}
450-
451464
static unsigned
452465
omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
453466
{

0 commit comments

Comments
 (0)