diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/omap2_mcspi.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 27a3fa1f3bf4..2a651e61bfbf 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c | |||
@@ -296,6 +296,19 @@ static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi) | |||
296 | return 0; | 296 | return 0; |
297 | } | 297 | } |
298 | 298 | ||
299 | static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) | ||
300 | { | ||
301 | unsigned long timeout; | ||
302 | |||
303 | timeout = jiffies + msecs_to_jiffies(1000); | ||
304 | while (!(__raw_readl(reg) & bit)) { | ||
305 | if (time_after(jiffies, timeout)) | ||
306 | return -1; | ||
307 | cpu_relax(); | ||
308 | } | ||
309 | return 0; | ||
310 | } | ||
311 | |||
299 | static unsigned | 312 | static unsigned |
300 | omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | 313 | omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) |
301 | { | 314 | { |
@@ -309,11 +322,14 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
309 | u32 l; | 322 | u32 l; |
310 | u8 * rx; | 323 | u8 * rx; |
311 | const u8 * tx; | 324 | const u8 * tx; |
325 | void __iomem *chstat_reg; | ||
312 | 326 | ||
313 | mcspi = spi_master_get_devdata(spi->master); | 327 | mcspi = spi_master_get_devdata(spi->master); |
314 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 328 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
315 | l = mcspi_cached_chconf0(spi); | 329 | l = mcspi_cached_chconf0(spi); |
316 | 330 | ||
331 | chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; | ||
332 | |||
317 | count = xfer->len; | 333 | count = xfer->len; |
318 | c = count; | 334 | c = count; |
319 | word_len = cs->word_len; | 335 | word_len = cs->word_len; |
@@ -382,6 +398,16 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
382 | if (tx != NULL) { | 398 | if (tx != NULL) { |
383 | wait_for_completion(&mcspi_dma->dma_tx_completion); | 399 | wait_for_completion(&mcspi_dma->dma_tx_completion); |
384 | dma_unmap_single(NULL, xfer->tx_dma, count, DMA_TO_DEVICE); | 400 | dma_unmap_single(NULL, xfer->tx_dma, count, DMA_TO_DEVICE); |
401 | |||
402 | /* for TX_ONLY mode, be sure all words have shifted out */ | ||
403 | if (rx == NULL) { | ||
404 | if (mcspi_wait_for_reg_bit(chstat_reg, | ||
405 | OMAP2_MCSPI_CHSTAT_TXS) < 0) | ||
406 | dev_err(&spi->dev, "TXS timed out\n"); | ||
407 | else if (mcspi_wait_for_reg_bit(chstat_reg, | ||
408 | OMAP2_MCSPI_CHSTAT_EOT) < 0) | ||
409 | dev_err(&spi->dev, "EOT timed out\n"); | ||
410 | } | ||
385 | } | 411 | } |
386 | 412 | ||
387 | if (rx != NULL) { | 413 | if (rx != NULL) { |
@@ -435,19 +461,6 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
435 | return count; | 461 | return count; |
436 | } | 462 | } |
437 | 463 | ||
438 | static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) | ||
439 | { | ||
440 | unsigned long timeout; | ||
441 | |||
442 | timeout = jiffies + msecs_to_jiffies(1000); | ||
443 | while (!(__raw_readl(reg) & bit)) { | ||
444 | if (time_after(jiffies, timeout)) | ||
445 | return -1; | ||
446 | cpu_relax(); | ||
447 | } | ||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static unsigned | 464 | static unsigned |
452 | omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) | 465 | omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer) |
453 | { | 466 | { |