Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: omap2_mcspi PIO RX fix

Before transmission of the last word in PIO RX_ONLY mode rx+tx mode
is enabled:

/* prevent last RX_ONLY read from triggering
* more word i/o: switch to rx+tx
*/
if (c == 0 && tx == NULL)
mcspi_write_cs_reg(spi,
OMAP2_MCSPI_CHCONF0, l);

But because c is decremented after the test, c will never be zero and
rx+tx will not be enabled. This breaks RX_ONLY mode PIO transfers.

Fix it by decrementing c in the beginning of the various I/O loops.

Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Kalle Valo and committed by
Linus Torvalds
feed9bab dbcc2ec6

+3 -3
+3 -3
drivers/spi/omap2_mcspi.c
··· 350 tx = xfer->tx_buf; 351 352 do { 353 if (tx != NULL) { 354 if (mcspi_wait_for_reg_bit(chstat_reg, 355 OMAP2_MCSPI_CHSTAT_TXS) < 0) { ··· 381 word_len, *(rx - 1)); 382 #endif 383 } 384 - c -= 1; 385 } while (c); 386 } else if (word_len <= 16) { 387 u16 *rx; ··· 389 rx = xfer->rx_buf; 390 tx = xfer->tx_buf; 391 do { 392 if (tx != NULL) { 393 if (mcspi_wait_for_reg_bit(chstat_reg, 394 OMAP2_MCSPI_CHSTAT_TXS) < 0) { ··· 420 word_len, *(rx - 1)); 421 #endif 422 } 423 - c -= 2; 424 } while (c); 425 } else if (word_len <= 32) { 426 u32 *rx; ··· 428 rx = xfer->rx_buf; 429 tx = xfer->tx_buf; 430 do { 431 if (tx != NULL) { 432 if (mcspi_wait_for_reg_bit(chstat_reg, 433 OMAP2_MCSPI_CHSTAT_TXS) < 0) { ··· 459 word_len, *(rx - 1)); 460 #endif 461 } 462 - c -= 4; 463 } while (c); 464 } 465
··· 350 tx = xfer->tx_buf; 351 352 do { 353 + c -= 1; 354 if (tx != NULL) { 355 if (mcspi_wait_for_reg_bit(chstat_reg, 356 OMAP2_MCSPI_CHSTAT_TXS) < 0) { ··· 380 word_len, *(rx - 1)); 381 #endif 382 } 383 } while (c); 384 } else if (word_len <= 16) { 385 u16 *rx; ··· 389 rx = xfer->rx_buf; 390 tx = xfer->tx_buf; 391 do { 392 + c -= 2; 393 if (tx != NULL) { 394 if (mcspi_wait_for_reg_bit(chstat_reg, 395 OMAP2_MCSPI_CHSTAT_TXS) < 0) { ··· 419 word_len, *(rx - 1)); 420 #endif 421 } 422 } while (c); 423 } else if (word_len <= 32) { 424 u32 *rx; ··· 428 rx = xfer->rx_buf; 429 tx = xfer->tx_buf; 430 do { 431 + c -= 4; 432 if (tx != NULL) { 433 if (mcspi_wait_for_reg_bit(chstat_reg, 434 OMAP2_MCSPI_CHSTAT_TXS) < 0) { ··· 458 word_len, *(rx - 1)); 459 #endif 460 } 461 } while (c); 462 } 463