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