diff options
author | Kalle Valo <kalle.valo@nokia.com> | 2008-01-24 17:00:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-01-24 17:06:44 -0500 |
commit | feed9bab7b14b77be8d796bcee95e2343fb82955 (patch) | |
tree | d46191244459c4dd4c5f6e0ad0c832eaa7894af8 | |
parent | dbcc2ec60fe15448e5dfe4153f7347ac82b4da73 (diff) |
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>
-rw-r--r-- | drivers/spi/omap2_mcspi.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 3cdab131c4a9..ea61724ae225 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c | |||
@@ -350,6 +350,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
350 | tx = xfer->tx_buf; | 350 | tx = xfer->tx_buf; |
351 | 351 | ||
352 | do { | 352 | do { |
353 | c -= 1; | ||
353 | if (tx != NULL) { | 354 | if (tx != NULL) { |
354 | if (mcspi_wait_for_reg_bit(chstat_reg, | 355 | if (mcspi_wait_for_reg_bit(chstat_reg, |
355 | OMAP2_MCSPI_CHSTAT_TXS) < 0) { | 356 | OMAP2_MCSPI_CHSTAT_TXS) < 0) { |
@@ -380,7 +381,6 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
380 | word_len, *(rx - 1)); | 381 | word_len, *(rx - 1)); |
381 | #endif | 382 | #endif |
382 | } | 383 | } |
383 | c -= 1; | ||
384 | } while (c); | 384 | } while (c); |
385 | } else if (word_len <= 16) { | 385 | } else if (word_len <= 16) { |
386 | u16 *rx; | 386 | u16 *rx; |
@@ -389,6 +389,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
389 | rx = xfer->rx_buf; | 389 | rx = xfer->rx_buf; |
390 | tx = xfer->tx_buf; | 390 | tx = xfer->tx_buf; |
391 | do { | 391 | do { |
392 | c -= 2; | ||
392 | if (tx != NULL) { | 393 | if (tx != NULL) { |
393 | if (mcspi_wait_for_reg_bit(chstat_reg, | 394 | if (mcspi_wait_for_reg_bit(chstat_reg, |
394 | OMAP2_MCSPI_CHSTAT_TXS) < 0) { | 395 | OMAP2_MCSPI_CHSTAT_TXS) < 0) { |
@@ -419,7 +420,6 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
419 | word_len, *(rx - 1)); | 420 | word_len, *(rx - 1)); |
420 | #endif | 421 | #endif |
421 | } | 422 | } |
422 | c -= 2; | ||
423 | } while (c); | 423 | } while (c); |
424 | } else if (word_len <= 32) { | 424 | } else if (word_len <= 32) { |
425 | u32 *rx; | 425 | u32 *rx; |
@@ -428,6 +428,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
428 | rx = xfer->rx_buf; | 428 | rx = xfer->rx_buf; |
429 | tx = xfer->tx_buf; | 429 | tx = xfer->tx_buf; |
430 | do { | 430 | do { |
431 | c -= 4; | ||
431 | if (tx != NULL) { | 432 | if (tx != NULL) { |
432 | if (mcspi_wait_for_reg_bit(chstat_reg, | 433 | if (mcspi_wait_for_reg_bit(chstat_reg, |
433 | OMAP2_MCSPI_CHSTAT_TXS) < 0) { | 434 | OMAP2_MCSPI_CHSTAT_TXS) < 0) { |
@@ -458,7 +459,6 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | |||
458 | word_len, *(rx - 1)); | 459 | word_len, *(rx - 1)); |
459 | #endif | 460 | #endif |
460 | } | 461 | } |
461 | c -= 4; | ||
462 | } while (c); | 462 | } while (c); |
463 | } | 463 | } |
464 | 464 | ||