diff options
Diffstat (limited to 'drivers/spi/spi-omap2-mcspi.c')
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 62 |
1 files changed, 17 insertions, 45 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 0caa3c8bef46..43a02e377b3b 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -423,16 +423,12 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, | |||
423 | 423 | ||
424 | if (mcspi_dma->dma_tx) { | 424 | if (mcspi_dma->dma_tx) { |
425 | struct dma_async_tx_descriptor *tx; | 425 | struct dma_async_tx_descriptor *tx; |
426 | struct scatterlist sg; | ||
427 | 426 | ||
428 | dmaengine_slave_config(mcspi_dma->dma_tx, &cfg); | 427 | dmaengine_slave_config(mcspi_dma->dma_tx, &cfg); |
429 | 428 | ||
430 | sg_init_table(&sg, 1); | 429 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, xfer->tx_sg.sgl, |
431 | sg_dma_address(&sg) = xfer->tx_dma; | 430 | xfer->tx_sg.nents, DMA_MEM_TO_DEV, |
432 | sg_dma_len(&sg) = xfer->len; | 431 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
433 | |||
434 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1, | ||
435 | DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
436 | if (tx) { | 432 | if (tx) { |
437 | tx->callback = omap2_mcspi_tx_callback; | 433 | tx->callback = omap2_mcspi_tx_callback; |
438 | tx->callback_param = spi; | 434 | tx->callback_param = spi; |
@@ -478,20 +474,15 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, | |||
478 | 474 | ||
479 | if (mcspi_dma->dma_rx) { | 475 | if (mcspi_dma->dma_rx) { |
480 | struct dma_async_tx_descriptor *tx; | 476 | struct dma_async_tx_descriptor *tx; |
481 | struct scatterlist sg; | ||
482 | 477 | ||
483 | dmaengine_slave_config(mcspi_dma->dma_rx, &cfg); | 478 | dmaengine_slave_config(mcspi_dma->dma_rx, &cfg); |
484 | 479 | ||
485 | if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0) | 480 | if ((l & OMAP2_MCSPI_CHCONF_TURBO) && mcspi->fifo_depth == 0) |
486 | dma_count -= es; | 481 | dma_count -= es; |
487 | 482 | ||
488 | sg_init_table(&sg, 1); | 483 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, xfer->rx_sg.sgl, |
489 | sg_dma_address(&sg) = xfer->rx_dma; | 484 | xfer->rx_sg.nents, DMA_DEV_TO_MEM, |
490 | sg_dma_len(&sg) = dma_count; | 485 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
491 | |||
492 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1, | ||
493 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | | ||
494 | DMA_CTRL_ACK); | ||
495 | if (tx) { | 486 | if (tx) { |
496 | tx->callback = omap2_mcspi_rx_callback; | 487 | tx->callback = omap2_mcspi_rx_callback; |
497 | tx->callback_param = spi; | 488 | tx->callback_param = spi; |
@@ -505,8 +496,6 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, | |||
505 | omap2_mcspi_set_dma_req(spi, 1, 1); | 496 | omap2_mcspi_set_dma_req(spi, 1, 1); |
506 | 497 | ||
507 | wait_for_completion(&mcspi_dma->dma_rx_completion); | 498 | wait_for_completion(&mcspi_dma->dma_rx_completion); |
508 | dma_unmap_single(mcspi->dev, xfer->rx_dma, count, | ||
509 | DMA_FROM_DEVICE); | ||
510 | 499 | ||
511 | if (mcspi->fifo_depth > 0) | 500 | if (mcspi->fifo_depth > 0) |
512 | return count; | 501 | return count; |
@@ -619,8 +608,6 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
619 | 608 | ||
620 | if (tx != NULL) { | 609 | if (tx != NULL) { |
621 | wait_for_completion(&mcspi_dma->dma_tx_completion); | 610 | wait_for_completion(&mcspi_dma->dma_tx_completion); |
622 | dma_unmap_single(mcspi->dev, xfer->tx_dma, xfer->len, | ||
623 | DMA_TO_DEVICE); | ||
624 | 611 | ||
625 | if (mcspi->fifo_depth > 0) { | 612 | if (mcspi->fifo_depth > 0) { |
626 | irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS; | 613 | irqstat_reg = mcspi->base + OMAP2_MCSPI_IRQSTATUS; |
@@ -1087,6 +1074,16 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) | |||
1087 | gpio_free(spi->cs_gpio); | 1074 | gpio_free(spi->cs_gpio); |
1088 | } | 1075 | } |
1089 | 1076 | ||
1077 | static bool omap2_mcspi_can_dma(struct spi_master *master, | ||
1078 | struct spi_device *spi, | ||
1079 | struct spi_transfer *xfer) | ||
1080 | { | ||
1081 | if (xfer->len < DMA_MIN_BYTES) | ||
1082 | return false; | ||
1083 | |||
1084 | return true; | ||
1085 | } | ||
1086 | |||
1090 | static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi, | 1087 | static int omap2_mcspi_work_one(struct omap2_mcspi *mcspi, |
1091 | struct spi_device *spi, struct spi_transfer *t) | 1088 | struct spi_device *spi, struct spi_transfer *t) |
1092 | { | 1089 | { |
@@ -1268,32 +1265,6 @@ static int omap2_mcspi_transfer_one(struct spi_master *master, | |||
1268 | return -EINVAL; | 1265 | return -EINVAL; |
1269 | } | 1266 | } |
1270 | 1267 | ||
1271 | if (len < DMA_MIN_BYTES) | ||
1272 | goto skip_dma_map; | ||
1273 | |||
1274 | if (mcspi_dma->dma_tx && tx_buf != NULL) { | ||
1275 | t->tx_dma = dma_map_single(mcspi->dev, (void *) tx_buf, | ||
1276 | len, DMA_TO_DEVICE); | ||
1277 | if (dma_mapping_error(mcspi->dev, t->tx_dma)) { | ||
1278 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", | ||
1279 | 'T', len); | ||
1280 | return -EINVAL; | ||
1281 | } | ||
1282 | } | ||
1283 | if (mcspi_dma->dma_rx && rx_buf != NULL) { | ||
1284 | t->rx_dma = dma_map_single(mcspi->dev, rx_buf, t->len, | ||
1285 | DMA_FROM_DEVICE); | ||
1286 | if (dma_mapping_error(mcspi->dev, t->rx_dma)) { | ||
1287 | dev_dbg(mcspi->dev, "dma %cX %d bytes error\n", | ||
1288 | 'R', len); | ||
1289 | if (tx_buf != NULL) | ||
1290 | dma_unmap_single(mcspi->dev, t->tx_dma, | ||
1291 | len, DMA_TO_DEVICE); | ||
1292 | return -EINVAL; | ||
1293 | } | ||
1294 | } | ||
1295 | |||
1296 | skip_dma_map: | ||
1297 | return omap2_mcspi_work_one(mcspi, spi, t); | 1268 | return omap2_mcspi_work_one(mcspi, spi, t); |
1298 | } | 1269 | } |
1299 | 1270 | ||
@@ -1377,6 +1348,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) | |||
1377 | master->transfer_one = omap2_mcspi_transfer_one; | 1348 | master->transfer_one = omap2_mcspi_transfer_one; |
1378 | master->set_cs = omap2_mcspi_set_cs; | 1349 | master->set_cs = omap2_mcspi_set_cs; |
1379 | master->cleanup = omap2_mcspi_cleanup; | 1350 | master->cleanup = omap2_mcspi_cleanup; |
1351 | master->can_dma = omap2_mcspi_can_dma; | ||
1380 | master->dev.of_node = node; | 1352 | master->dev.of_node = node; |
1381 | master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; | 1353 | master->max_speed_hz = OMAP2_MCSPI_MAX_FREQ; |
1382 | master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15; | 1354 | master->min_speed_hz = OMAP2_MCSPI_MAX_FREQ >> 15; |