aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHaavard Skinnemoen <hskinnemoen@atmel.com>2007-06-01 03:47:00 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-01 11:18:29 -0400
commit5a9a62bb035b1f74e7d017e3bd48d1c687d7de3c (patch)
tree0f4d5474d750ade240f399c0dc8335debfc15c02 /drivers
parente88b34bade55a51dd23a50de0ac5076cbbb8f4fd (diff)
atmel_spi dma address bugfix
When either rx_buf or tx_buf is not being used, i.e. for plain read- or write operations, the atmel_spi uses a fixed-size DMA buffer instead. If the transfer is longer than the size of this buffer, it is split into multiple DMA transfers. When the transfer is split like this, the atmel_spi driver ends up using the same DMA address again and again even for the buffer that came from the user, which is of course wrong. Fix this by adding the number of bytes already transferred to the DMA address so that the data ends up in the right place. Thanks to Wu Xuan for discovering this bug. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/atmel_spi.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 1d8a2f6bb8eb..8b2601de3630 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -113,16 +113,16 @@ static void atmel_spi_next_xfer(struct spi_master *master,
113 113
114 len = as->remaining_bytes; 114 len = as->remaining_bytes;
115 115
116 tx_dma = xfer->tx_dma; 116 tx_dma = xfer->tx_dma + xfer->len - len;
117 rx_dma = xfer->rx_dma; 117 rx_dma = xfer->rx_dma + xfer->len - len;
118 118
119 /* use scratch buffer only when rx or tx data is unspecified */ 119 /* use scratch buffer only when rx or tx data is unspecified */
120 if (rx_dma == INVALID_DMA_ADDRESS) { 120 if (!xfer->rx_buf) {
121 rx_dma = as->buffer_dma; 121 rx_dma = as->buffer_dma;
122 if (len > BUFFER_SIZE) 122 if (len > BUFFER_SIZE)
123 len = BUFFER_SIZE; 123 len = BUFFER_SIZE;
124 } 124 }
125 if (tx_dma == INVALID_DMA_ADDRESS) { 125 if (!xfer->tx_buf) {
126 tx_dma = as->buffer_dma; 126 tx_dma = as->buffer_dma;
127 if (len > BUFFER_SIZE) 127 if (len > BUFFER_SIZE)
128 len = BUFFER_SIZE; 128 len = BUFFER_SIZE;