summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-sirf.c
diff options
context:
space:
mode:
authorQipan Li <Qipan.Li@csr.com>2013-08-25 09:42:50 -0400
committerMark Brown <broonie@linaro.org>2013-08-26 08:00:14 -0400
commit692fb0fe5aacea861e4006342029cf505a7dbe18 (patch)
tree34e0abbfe07112687885f2097fa893fc7f3b7b12 /drivers/spi/spi-sirf.c
parent6cca9e2dd01adfa46a3b81f54f80d318714da418 (diff)
spi/sirf: fix the misunderstanding about len of spi_transfer
the unit of len of spi_transfer is in bytes, not in spi words. the old codes misunderstood that and thought the len is the amount of spi words. but it is actually how many bytes existing in the spi buffer. this patch fixes that and also rename left_tx_cnt and left_rx_cnt to left_tx_word and left_rx_word to highlight they are in words. Signed-off-by: Qipan Li <Qipan.Li@csr.com> Signed-off-by: Barry Song <Baohua.Song@csr.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-sirf.c')
-rw-r--r--drivers/spi/spi-sirf.c47
1 files changed, 24 insertions, 23 deletions
diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c
index acfca880fe84..4461cdc7415d 100644
--- a/drivers/spi/spi-sirf.c
+++ b/drivers/spi/spi-sirf.c
@@ -130,8 +130,7 @@
130 130
131#define ALIGNED(x) (!((u32)x & 0x3)) 131#define ALIGNED(x) (!((u32)x & 0x3))
132#define IS_DMA_VALID(x) (x && ALIGNED(x->tx_buf) && ALIGNED(x->rx_buf) && \ 132#define IS_DMA_VALID(x) (x && ALIGNED(x->tx_buf) && ALIGNED(x->rx_buf) && \
133 ALIGNED(x->len * sspi->word_width) && (x->len * sspi->word_width < \ 133 ALIGNED(x->len) && (x->len < 2 * PAGE_SIZE))
134 2 * PAGE_SIZE))
135 134
136struct sirfsoc_spi { 135struct sirfsoc_spi {
137 struct spi_bitbang bitbang; 136 struct spi_bitbang bitbang;
@@ -152,8 +151,8 @@ struct sirfsoc_spi {
152 void (*tx_word) (struct sirfsoc_spi *); 151 void (*tx_word) (struct sirfsoc_spi *);
153 152
154 /* number of words left to be tranmitted/received */ 153 /* number of words left to be tranmitted/received */
155 unsigned int left_tx_cnt; 154 unsigned int left_tx_word;
156 unsigned int left_rx_cnt; 155 unsigned int left_rx_word;
157 156
158 /* rx & tx DMA channels */ 157 /* rx & tx DMA channels */
159 struct dma_chan *rx_chan; 158 struct dma_chan *rx_chan;
@@ -178,7 +177,7 @@ static void spi_sirfsoc_rx_word_u8(struct sirfsoc_spi *sspi)
178 sspi->rx = rx; 177 sspi->rx = rx;
179 } 178 }
180 179
181 sspi->left_rx_cnt--; 180 sspi->left_rx_word--;
182} 181}
183 182
184static void spi_sirfsoc_tx_word_u8(struct sirfsoc_spi *sspi) 183static void spi_sirfsoc_tx_word_u8(struct sirfsoc_spi *sspi)
@@ -192,7 +191,7 @@ static void spi_sirfsoc_tx_word_u8(struct sirfsoc_spi *sspi)
192 } 191 }
193 192
194 writel(data, sspi->base + SIRFSOC_SPI_TXFIFO_DATA); 193 writel(data, sspi->base + SIRFSOC_SPI_TXFIFO_DATA);
195 sspi->left_tx_cnt--; 194 sspi->left_tx_word--;
196} 195}
197 196
198static void spi_sirfsoc_rx_word_u16(struct sirfsoc_spi *sspi) 197static void spi_sirfsoc_rx_word_u16(struct sirfsoc_spi *sspi)
@@ -207,7 +206,7 @@ static void spi_sirfsoc_rx_word_u16(struct sirfsoc_spi *sspi)
207 sspi->rx = rx; 206 sspi->rx = rx;
208 } 207 }
209 208
210 sspi->left_rx_cnt--; 209 sspi->left_rx_word--;
211} 210}
212 211
213static void spi_sirfsoc_tx_word_u16(struct sirfsoc_spi *sspi) 212static void spi_sirfsoc_tx_word_u16(struct sirfsoc_spi *sspi)
@@ -221,7 +220,7 @@ static void spi_sirfsoc_tx_word_u16(struct sirfsoc_spi *sspi)
221 } 220 }
222 221
223 writel(data, sspi->base + SIRFSOC_SPI_TXFIFO_DATA); 222 writel(data, sspi->base + SIRFSOC_SPI_TXFIFO_DATA);
224 sspi->left_tx_cnt--; 223 sspi->left_tx_word--;
225} 224}
226 225
227static void spi_sirfsoc_rx_word_u32(struct sirfsoc_spi *sspi) 226static void spi_sirfsoc_rx_word_u32(struct sirfsoc_spi *sspi)
@@ -236,7 +235,7 @@ static void spi_sirfsoc_rx_word_u32(struct sirfsoc_spi *sspi)
236 sspi->rx = rx; 235 sspi->rx = rx;
237 } 236 }
238 237
239 sspi->left_rx_cnt--; 238 sspi->left_rx_word--;
240 239
241} 240}
242 241
@@ -251,7 +250,7 @@ static void spi_sirfsoc_tx_word_u32(struct sirfsoc_spi *sspi)
251 } 250 }
252 251
253 writel(data, sspi->base + SIRFSOC_SPI_TXFIFO_DATA); 252 writel(data, sspi->base + SIRFSOC_SPI_TXFIFO_DATA);
254 sspi->left_tx_cnt--; 253 sspi->left_tx_word--;
255} 254}
256 255
257static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id) 256static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id)
@@ -272,18 +271,18 @@ static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id)
272 | SIRFSOC_SPI_RXFIFO_THD_REACH)) 271 | SIRFSOC_SPI_RXFIFO_THD_REACH))
273 while (!((readl(sspi->base + SIRFSOC_SPI_RXFIFO_STATUS) 272 while (!((readl(sspi->base + SIRFSOC_SPI_RXFIFO_STATUS)
274 & SIRFSOC_SPI_FIFO_EMPTY)) && 273 & SIRFSOC_SPI_FIFO_EMPTY)) &&
275 sspi->left_rx_cnt) 274 sspi->left_rx_word)
276 sspi->rx_word(sspi); 275 sspi->rx_word(sspi);
277 276
278 if (spi_stat & (SIRFSOC_SPI_FIFO_EMPTY 277 if (spi_stat & (SIRFSOC_SPI_FIFO_EMPTY
279 | SIRFSOC_SPI_TXFIFO_THD_REACH)) 278 | SIRFSOC_SPI_TXFIFO_THD_REACH))
280 while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS) 279 while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS)
281 & SIRFSOC_SPI_FIFO_FULL)) && 280 & SIRFSOC_SPI_FIFO_FULL)) &&
282 sspi->left_tx_cnt) 281 sspi->left_tx_word)
283 sspi->tx_word(sspi); 282 sspi->tx_word(sspi);
284 283
285 /* Received all words */ 284 /* Received all words */
286 if ((sspi->left_rx_cnt == 0) && (sspi->left_tx_cnt == 0)) { 285 if ((sspi->left_rx_word == 0) && (sspi->left_tx_word == 0)) {
287 complete(&sspi->rx_done); 286 complete(&sspi->rx_done);
288 writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN); 287 writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
289 } 288 }
@@ -305,25 +304,28 @@ static int spi_sirfsoc_transfer(struct spi_device *spi, struct spi_transfer *t)
305 304
306 sspi->tx = t->tx_buf ? t->tx_buf : sspi->dummypage; 305 sspi->tx = t->tx_buf ? t->tx_buf : sspi->dummypage;
307 sspi->rx = t->rx_buf ? t->rx_buf : sspi->dummypage; 306 sspi->rx = t->rx_buf ? t->rx_buf : sspi->dummypage;
308 sspi->left_tx_cnt = sspi->left_rx_cnt = t->len; 307 sspi->left_tx_word = sspi->left_rx_word = t->len / sspi->word_width;
309 INIT_COMPLETION(sspi->rx_done); 308 INIT_COMPLETION(sspi->rx_done);
310 INIT_COMPLETION(sspi->tx_done); 309 INIT_COMPLETION(sspi->tx_done);
311 310
312 writel(SIRFSOC_SPI_INT_MASK_ALL, sspi->base + SIRFSOC_SPI_INT_STATUS); 311 writel(SIRFSOC_SPI_INT_MASK_ALL, sspi->base + SIRFSOC_SPI_INT_STATUS);
313 312
314 if (t->len == 1) { 313 if (sspi->left_tx_word == 1) {
315 writel(readl(sspi->base + SIRFSOC_SPI_CTRL) | 314 writel(readl(sspi->base + SIRFSOC_SPI_CTRL) |
316 SIRFSOC_SPI_ENA_AUTO_CLR, 315 SIRFSOC_SPI_ENA_AUTO_CLR,
317 sspi->base + SIRFSOC_SPI_CTRL); 316 sspi->base + SIRFSOC_SPI_CTRL);
318 writel(0, sspi->base + SIRFSOC_SPI_TX_DMA_IO_LEN); 317 writel(0, sspi->base + SIRFSOC_SPI_TX_DMA_IO_LEN);
319 writel(0, sspi->base + SIRFSOC_SPI_RX_DMA_IO_LEN); 318 writel(0, sspi->base + SIRFSOC_SPI_RX_DMA_IO_LEN);
320 } else if ((t->len > 1) && (t->len < SIRFSOC_SPI_DAT_FRM_LEN_MAX)) { 319 } else if ((sspi->left_tx_word > 1) && (sspi->left_tx_word <
320 SIRFSOC_SPI_DAT_FRM_LEN_MAX)) {
321 writel(readl(sspi->base + SIRFSOC_SPI_CTRL) | 321 writel(readl(sspi->base + SIRFSOC_SPI_CTRL) |
322 SIRFSOC_SPI_MUL_DAT_MODE | 322 SIRFSOC_SPI_MUL_DAT_MODE |
323 SIRFSOC_SPI_ENA_AUTO_CLR, 323 SIRFSOC_SPI_ENA_AUTO_CLR,
324 sspi->base + SIRFSOC_SPI_CTRL); 324 sspi->base + SIRFSOC_SPI_CTRL);
325 writel(t->len - 1, sspi->base + SIRFSOC_SPI_TX_DMA_IO_LEN); 325 writel(sspi->left_tx_word - 1,
326 writel(t->len - 1, sspi->base + SIRFSOC_SPI_RX_DMA_IO_LEN); 326 sspi->base + SIRFSOC_SPI_TX_DMA_IO_LEN);
327 writel(sspi->left_tx_word - 1,
328 sspi->base + SIRFSOC_SPI_RX_DMA_IO_LEN);
327 } else { 329 } else {
328 writel(readl(sspi->base + SIRFSOC_SPI_CTRL), 330 writel(readl(sspi->base + SIRFSOC_SPI_CTRL),
329 sspi->base + SIRFSOC_SPI_CTRL); 331 sspi->base + SIRFSOC_SPI_CTRL);
@@ -338,18 +340,17 @@ static int spi_sirfsoc_transfer(struct spi_device *spi, struct spi_transfer *t)
338 340
339 if (IS_DMA_VALID(t)) { 341 if (IS_DMA_VALID(t)) {
340 struct dma_async_tx_descriptor *rx_desc, *tx_desc; 342 struct dma_async_tx_descriptor *rx_desc, *tx_desc;
341 unsigned int size = t->len * sspi->word_width;
342 343
343 sspi->dst_start = dma_map_single(&spi->dev, sspi->rx, t->len, DMA_FROM_DEVICE); 344 sspi->dst_start = dma_map_single(&spi->dev, sspi->rx, t->len, DMA_FROM_DEVICE);
344 rx_desc = dmaengine_prep_slave_single(sspi->rx_chan, 345 rx_desc = dmaengine_prep_slave_single(sspi->rx_chan,
345 sspi->dst_start, size, DMA_DEV_TO_MEM, 346 sspi->dst_start, t->len, DMA_DEV_TO_MEM,
346 DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 347 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
347 rx_desc->callback = spi_sirfsoc_dma_fini_callback; 348 rx_desc->callback = spi_sirfsoc_dma_fini_callback;
348 rx_desc->callback_param = &sspi->rx_done; 349 rx_desc->callback_param = &sspi->rx_done;
349 350
350 sspi->src_start = dma_map_single(&spi->dev, (void *)sspi->tx, t->len, DMA_TO_DEVICE); 351 sspi->src_start = dma_map_single(&spi->dev, (void *)sspi->tx, t->len, DMA_TO_DEVICE);
351 tx_desc = dmaengine_prep_slave_single(sspi->tx_chan, 352 tx_desc = dmaengine_prep_slave_single(sspi->tx_chan,
352 sspi->src_start, size, DMA_MEM_TO_DEV, 353 sspi->src_start, t->len, DMA_MEM_TO_DEV,
353 DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 354 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
354 tx_desc->callback = spi_sirfsoc_dma_fini_callback; 355 tx_desc->callback = spi_sirfsoc_dma_fini_callback;
355 tx_desc->callback_param = &sspi->tx_done; 356 tx_desc->callback_param = &sspi->tx_done;
@@ -377,7 +378,7 @@ static int spi_sirfsoc_transfer(struct spi_device *spi, struct spi_transfer *t)
377 dev_err(&spi->dev, "transfer timeout\n"); 378 dev_err(&spi->dev, "transfer timeout\n");
378 dmaengine_terminate_all(sspi->rx_chan); 379 dmaengine_terminate_all(sspi->rx_chan);
379 } else 380 } else
380 sspi->left_rx_cnt = 0; 381 sspi->left_rx_word = 0;
381 382
382 /* 383 /*
383 * we only wait tx-done event if transferring by DMA. for PIO, 384 * we only wait tx-done event if transferring by DMA. for PIO,
@@ -402,7 +403,7 @@ static int spi_sirfsoc_transfer(struct spi_device *spi, struct spi_transfer *t)
402 writel(0, sspi->base + SIRFSOC_SPI_TX_RX_EN); 403 writel(0, sspi->base + SIRFSOC_SPI_TX_RX_EN);
403 writel(0, sspi->base + SIRFSOC_SPI_INT_EN); 404 writel(0, sspi->base + SIRFSOC_SPI_INT_EN);
404 405
405 return t->len - sspi->left_rx_cnt; 406 return t->len - sspi->left_rx_word * sspi->word_width;
406} 407}
407 408
408static void spi_sirfsoc_chipselect(struct spi_device *spi, int value) 409static void spi_sirfsoc_chipselect(struct spi_device *spi, int value)