diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2014-06-02 09:38:06 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-06-02 10:49:32 -0400 |
commit | b42e03596db3d45980c976c8124fdc323f031dc4 (patch) | |
tree | ca86553f877340af468414c0e634df98ac018c47 | |
parent | 9c5de2c1754c2bb3c69c4d7bf0d0edc0a61d8232 (diff) |
spi: rspi: Use core SPI_MASTER_MUST_[RT]X handling
RSPI needs dummy transfers to generate the SPI clock on receive.
RSPI-RZ and QSPI always do both transmit and receive.
Use the SPI core SPI_MASTER_MUST_RX/SPI_MASTER_MUST_TX infrastructure
instead of checking for the presence of buffers and providing dummy data
ourselves (for PIO), or providing a dummy buffer (for DMA).
rspi_receive_dma() now provides full duplex DMA transfers on RSPI, and is
renamed to rspi_send_receive_dma().
As the SPI core will always provide a TX buffer, the logic to choose
between DMA send and DMA send/receive in rspi_transfer_one() now has to
check for the presence of an RX buffer. Likewise for the DMA availability
tests in rspi_is_dma().
The buffer tests in qspi_transfer_one() are now always true, so they're
removed.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | drivers/spi/spi-rspi.c | 132 |
1 files changed, 58 insertions, 74 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 3bd06fd9af47..ece8f6037943 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
@@ -183,8 +183,6 @@ | |||
183 | #define SPBFCR_TXTRG_MASK 0x30 /* Transmit Buffer Data Triggering Number */ | 183 | #define SPBFCR_TXTRG_MASK 0x30 /* Transmit Buffer Data Triggering Number */ |
184 | #define SPBFCR_RXTRG_MASK 0x07 /* Receive Buffer Data Triggering Number */ | 184 | #define SPBFCR_RXTRG_MASK 0x07 /* Receive Buffer Data Triggering Number */ |
185 | 185 | ||
186 | #define DUMMY_DATA 0x00 | ||
187 | |||
188 | struct rspi_data { | 186 | struct rspi_data { |
189 | void __iomem *addr; | 187 | void __iomem *addr; |
190 | u32 max_speed_hz; | 188 | u32 max_speed_hz; |
@@ -252,6 +250,7 @@ struct spi_ops { | |||
252 | int (*transfer_one)(struct spi_master *master, struct spi_device *spi, | 250 | int (*transfer_one)(struct spi_master *master, struct spi_device *spi, |
253 | struct spi_transfer *xfer); | 251 | struct spi_transfer *xfer); |
254 | u16 mode_bits; | 252 | u16 mode_bits; |
253 | u16 flags; | ||
255 | }; | 254 | }; |
256 | 255 | ||
257 | /* | 256 | /* |
@@ -552,42 +551,38 @@ static void qspi_receive_init(const struct rspi_data *rspi) | |||
552 | rspi_write8(rspi, 0, QSPI_SPBFCR); | 551 | rspi_write8(rspi, 0, QSPI_SPBFCR); |
553 | } | 552 | } |
554 | 553 | ||
555 | static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) | 554 | static int rspi_send_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) |
556 | { | 555 | { |
557 | struct scatterlist sg, sg_dummy; | 556 | struct scatterlist sg_rx, sg_tx; |
558 | void *dummy = NULL, *rx_buf = t->rx_buf; | 557 | const void *tx_buf = t->tx_buf; |
559 | struct dma_async_tx_descriptor *desc, *desc_dummy; | 558 | void *rx_buf = t->rx_buf; |
559 | struct dma_async_tx_descriptor *desc_tx, *desc_rx; | ||
560 | unsigned int len = t->len; | 560 | unsigned int len = t->len; |
561 | int ret = 0; | 561 | int ret = 0; |
562 | 562 | ||
563 | /* prepare dummy transfer to generate SPI clocks */ | 563 | /* prepare transmit transfer */ |
564 | dummy = kzalloc(len, GFP_KERNEL); | 564 | if (!rspi_dma_map_sg(&sg_tx, tx_buf, len, rspi->chan_tx, |
565 | if (!dummy) { | 565 | DMA_TO_DEVICE)) |
566 | ret = -ENOMEM; | 566 | return -EFAULT; |
567 | goto end_nomap; | 567 | |
568 | } | 568 | desc_tx = dmaengine_prep_slave_sg(rspi->chan_tx, &sg_tx, 1, |
569 | if (!rspi_dma_map_sg(&sg_dummy, dummy, len, rspi->chan_tx, | ||
570 | DMA_TO_DEVICE)) { | ||
571 | ret = -EFAULT; | ||
572 | goto end_nomap; | ||
573 | } | ||
574 | desc_dummy = dmaengine_prep_slave_sg(rspi->chan_tx, &sg_dummy, 1, | ||
575 | DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 569 | DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
576 | if (!desc_dummy) { | 570 | if (!desc_tx) { |
577 | ret = -EIO; | 571 | ret = -EIO; |
578 | goto end_dummy_mapped; | 572 | goto end_tx_mapped; |
579 | } | 573 | } |
580 | 574 | ||
581 | /* prepare receive transfer */ | 575 | /* prepare receive transfer */ |
582 | if (!rspi_dma_map_sg(&sg, rx_buf, len, rspi->chan_rx, | 576 | if (!rspi_dma_map_sg(&sg_rx, rx_buf, len, rspi->chan_rx, |
583 | DMA_FROM_DEVICE)) { | 577 | DMA_FROM_DEVICE)) { |
584 | ret = -EFAULT; | 578 | ret = -EFAULT; |
585 | goto end_dummy_mapped; | 579 | goto end_tx_mapped; |
586 | 580 | ||
587 | } | 581 | } |
588 | desc = dmaengine_prep_slave_sg(rspi->chan_rx, &sg, 1, DMA_FROM_DEVICE, | 582 | desc_rx = dmaengine_prep_slave_sg(rspi->chan_rx, &sg_rx, 1, |
589 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 583 | DMA_FROM_DEVICE, |
590 | if (!desc) { | 584 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
585 | if (!desc_rx) { | ||
591 | ret = -EIO; | 586 | ret = -EIO; |
592 | goto end; | 587 | goto end; |
593 | } | 588 | } |
@@ -606,13 +601,13 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) | |||
606 | rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); | 601 | rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); |
607 | rspi->dma_callbacked = 0; | 602 | rspi->dma_callbacked = 0; |
608 | 603 | ||
609 | desc->callback = rspi_dma_complete; | 604 | desc_rx->callback = rspi_dma_complete; |
610 | desc->callback_param = rspi; | 605 | desc_rx->callback_param = rspi; |
611 | dmaengine_submit(desc); | 606 | dmaengine_submit(desc_rx); |
612 | dma_async_issue_pending(rspi->chan_rx); | 607 | dma_async_issue_pending(rspi->chan_rx); |
613 | 608 | ||
614 | desc_dummy->callback = NULL; /* No callback */ | 609 | desc_tx->callback = NULL; /* No callback */ |
615 | dmaengine_submit(desc_dummy); | 610 | dmaengine_submit(desc_tx); |
616 | dma_async_issue_pending(rspi->chan_tx); | 611 | dma_async_issue_pending(rspi->chan_tx); |
617 | 612 | ||
618 | ret = wait_event_interruptible_timeout(rspi->wait, | 613 | ret = wait_event_interruptible_timeout(rspi->wait, |
@@ -628,21 +623,19 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) | |||
628 | enable_irq(rspi->rx_irq); | 623 | enable_irq(rspi->rx_irq); |
629 | 624 | ||
630 | end: | 625 | end: |
631 | rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE); | 626 | rspi_dma_unmap_sg(&sg_rx, rspi->chan_rx, DMA_FROM_DEVICE); |
632 | end_dummy_mapped: | 627 | end_tx_mapped: |
633 | rspi_dma_unmap_sg(&sg_dummy, rspi->chan_tx, DMA_TO_DEVICE); | 628 | rspi_dma_unmap_sg(&sg_tx, rspi->chan_tx, DMA_TO_DEVICE); |
634 | end_nomap: | ||
635 | kfree(dummy); | ||
636 | |||
637 | return ret; | 629 | return ret; |
638 | } | 630 | } |
639 | 631 | ||
640 | static int rspi_is_dma(const struct rspi_data *rspi, struct spi_transfer *t) | 632 | static int rspi_is_dma(const struct rspi_data *rspi, struct spi_transfer *t) |
641 | { | 633 | { |
642 | if (t->tx_buf && rspi->chan_tx) | ||
643 | return 1; | ||
644 | /* If the module receives data by DMAC, it also needs TX DMAC */ | 634 | /* If the module receives data by DMAC, it also needs TX DMAC */ |
645 | if (t->rx_buf && rspi->chan_tx && rspi->chan_rx) | 635 | if (t->rx_buf) |
636 | return rspi->chan_tx && rspi->chan_rx; | ||
637 | |||
638 | if (rspi->chan_tx) | ||
646 | return 1; | 639 | return 1; |
647 | 640 | ||
648 | return 0; | 641 | return 0; |
@@ -654,7 +647,7 @@ static int rspi_transfer_out_in(struct rspi_data *rspi, | |||
654 | int remain = xfer->len, ret; | 647 | int remain = xfer->len, ret; |
655 | const u8 *tx_buf = xfer->tx_buf; | 648 | const u8 *tx_buf = xfer->tx_buf; |
656 | u8 *rx_buf = xfer->rx_buf; | 649 | u8 *rx_buf = xfer->rx_buf; |
657 | u8 spcr, data; | 650 | u8 spcr; |
658 | 651 | ||
659 | spcr = rspi_read8(rspi, RSPI_SPCR); | 652 | spcr = rspi_read8(rspi, RSPI_SPCR); |
660 | if (rx_buf) { | 653 | if (rx_buf) { |
@@ -666,8 +659,7 @@ static int rspi_transfer_out_in(struct rspi_data *rspi, | |||
666 | rspi_write8(rspi, spcr, RSPI_SPCR); | 659 | rspi_write8(rspi, spcr, RSPI_SPCR); |
667 | 660 | ||
668 | while (remain > 0) { | 661 | while (remain > 0) { |
669 | data = tx_buf ? *tx_buf++ : DUMMY_DATA; | 662 | ret = rspi_data_out(rspi, *tx_buf++); |
670 | ret = rspi_data_out(rspi, data); | ||
671 | if (ret < 0) | 663 | if (ret < 0) |
672 | return ret; | 664 | return ret; |
673 | if (rx_buf) { | 665 | if (rx_buf) { |
@@ -689,20 +681,14 @@ static int rspi_transfer_one(struct spi_master *master, struct spi_device *spi, | |||
689 | struct spi_transfer *xfer) | 681 | struct spi_transfer *xfer) |
690 | { | 682 | { |
691 | struct rspi_data *rspi = spi_master_get_devdata(master); | 683 | struct rspi_data *rspi = spi_master_get_devdata(master); |
692 | int ret; | ||
693 | 684 | ||
694 | if (!rspi_is_dma(rspi, xfer)) | 685 | if (!rspi_is_dma(rspi, xfer)) |
695 | return rspi_transfer_out_in(rspi, xfer); | 686 | return rspi_transfer_out_in(rspi, xfer); |
696 | 687 | ||
697 | if (xfer->tx_buf) { | ||
698 | ret = rspi_send_dma(rspi, xfer); | ||
699 | if (ret < 0) | ||
700 | return ret; | ||
701 | } | ||
702 | if (xfer->rx_buf) | 688 | if (xfer->rx_buf) |
703 | return rspi_receive_dma(rspi, xfer); | 689 | return rspi_send_receive_dma(rspi, xfer); |
704 | 690 | else | |
705 | return 0; | 691 | return rspi_send_dma(rspi, xfer); |
706 | } | 692 | } |
707 | 693 | ||
708 | static int rspi_rz_transfer_out_in(struct rspi_data *rspi, | 694 | static int rspi_rz_transfer_out_in(struct rspi_data *rspi, |
@@ -711,17 +697,14 @@ static int rspi_rz_transfer_out_in(struct rspi_data *rspi, | |||
711 | int remain = xfer->len, ret; | 697 | int remain = xfer->len, ret; |
712 | const u8 *tx_buf = xfer->tx_buf; | 698 | const u8 *tx_buf = xfer->tx_buf; |
713 | u8 *rx_buf = xfer->rx_buf; | 699 | u8 *rx_buf = xfer->rx_buf; |
714 | u8 data; | ||
715 | 700 | ||
716 | rspi_rz_receive_init(rspi); | 701 | rspi_rz_receive_init(rspi); |
717 | 702 | ||
718 | while (remain > 0) { | 703 | while (remain > 0) { |
719 | data = tx_buf ? *tx_buf++ : DUMMY_DATA; | 704 | ret = rspi_data_out_in(rspi, *tx_buf++); |
720 | ret = rspi_data_out_in(rspi, data); | ||
721 | if (ret < 0) | 705 | if (ret < 0) |
722 | return ret; | 706 | return ret; |
723 | if (rx_buf) | 707 | *rx_buf++ = ret; |
724 | *rx_buf++ = ret; | ||
725 | remain--; | 708 | remain--; |
726 | } | 709 | } |
727 | 710 | ||
@@ -746,17 +729,14 @@ static int qspi_transfer_out_in(struct rspi_data *rspi, | |||
746 | int remain = xfer->len, ret; | 729 | int remain = xfer->len, ret; |
747 | const u8 *tx_buf = xfer->tx_buf; | 730 | const u8 *tx_buf = xfer->tx_buf; |
748 | u8 *rx_buf = xfer->rx_buf; | 731 | u8 *rx_buf = xfer->rx_buf; |
749 | u8 data; | ||
750 | 732 | ||
751 | qspi_receive_init(rspi); | 733 | qspi_receive_init(rspi); |
752 | 734 | ||
753 | while (remain > 0) { | 735 | while (remain > 0) { |
754 | data = tx_buf ? *tx_buf++ : DUMMY_DATA; | 736 | ret = rspi_data_out_in(rspi, *tx_buf++); |
755 | ret = rspi_data_out_in(rspi, data); | ||
756 | if (ret < 0) | 737 | if (ret < 0) |
757 | return ret; | 738 | return ret; |
758 | if (rx_buf) | 739 | *rx_buf++ = ret; |
759 | *rx_buf++ = ret; | ||
760 | remain--; | 740 | remain--; |
761 | } | 741 | } |
762 | 742 | ||
@@ -807,10 +787,10 @@ static int qspi_transfer_one(struct spi_master *master, struct spi_device *spi, | |||
807 | 787 | ||
808 | if (spi->mode & SPI_LOOP) { | 788 | if (spi->mode & SPI_LOOP) { |
809 | return qspi_transfer_out_in(rspi, xfer); | 789 | return qspi_transfer_out_in(rspi, xfer); |
810 | } else if (xfer->tx_buf && xfer->tx_nbits > SPI_NBITS_SINGLE) { | 790 | } else if (xfer->tx_nbits > SPI_NBITS_SINGLE) { |
811 | /* Quad or Dual SPI Write */ | 791 | /* Quad or Dual SPI Write */ |
812 | return qspi_transfer_out(rspi, xfer); | 792 | return qspi_transfer_out(rspi, xfer); |
813 | } else if (xfer->rx_buf && xfer->rx_nbits > SPI_NBITS_SINGLE) { | 793 | } else if (xfer->rx_nbits > SPI_NBITS_SINGLE) { |
814 | /* Quad or Dual SPI Read */ | 794 | /* Quad or Dual SPI Read */ |
815 | return qspi_transfer_in(rspi, xfer); | 795 | return qspi_transfer_in(rspi, xfer); |
816 | } else { | 796 | } else { |
@@ -1061,23 +1041,26 @@ static int rspi_remove(struct platform_device *pdev) | |||
1061 | } | 1041 | } |
1062 | 1042 | ||
1063 | static const struct spi_ops rspi_ops = { | 1043 | static const struct spi_ops rspi_ops = { |
1064 | .set_config_register = rspi_set_config_register, | 1044 | .set_config_register = rspi_set_config_register, |
1065 | .transfer_one = rspi_transfer_one, | 1045 | .transfer_one = rspi_transfer_one, |
1066 | .mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP, | 1046 | .mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP, |
1047 | .flags = SPI_MASTER_MUST_TX, | ||
1067 | }; | 1048 | }; |
1068 | 1049 | ||
1069 | static const struct spi_ops rspi_rz_ops = { | 1050 | static const struct spi_ops rspi_rz_ops = { |
1070 | .set_config_register = rspi_rz_set_config_register, | 1051 | .set_config_register = rspi_rz_set_config_register, |
1071 | .transfer_one = rspi_rz_transfer_one, | 1052 | .transfer_one = rspi_rz_transfer_one, |
1072 | .mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP, | 1053 | .mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP, |
1054 | .flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX, | ||
1073 | }; | 1055 | }; |
1074 | 1056 | ||
1075 | static const struct spi_ops qspi_ops = { | 1057 | static const struct spi_ops qspi_ops = { |
1076 | .set_config_register = qspi_set_config_register, | 1058 | .set_config_register = qspi_set_config_register, |
1077 | .transfer_one = qspi_transfer_one, | 1059 | .transfer_one = qspi_transfer_one, |
1078 | .mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP | | 1060 | .mode_bits = SPI_CPHA | SPI_CPOL | SPI_LOOP | |
1079 | SPI_TX_DUAL | SPI_TX_QUAD | | 1061 | SPI_TX_DUAL | SPI_TX_QUAD | |
1080 | SPI_RX_DUAL | SPI_RX_QUAD, | 1062 | SPI_RX_DUAL | SPI_RX_QUAD, |
1063 | .flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX, | ||
1081 | }; | 1064 | }; |
1082 | 1065 | ||
1083 | #ifdef CONFIG_OF | 1066 | #ifdef CONFIG_OF |
@@ -1197,6 +1180,7 @@ static int rspi_probe(struct platform_device *pdev) | |||
1197 | master->prepare_message = rspi_prepare_message; | 1180 | master->prepare_message = rspi_prepare_message; |
1198 | master->unprepare_message = rspi_unprepare_message; | 1181 | master->unprepare_message = rspi_unprepare_message; |
1199 | master->mode_bits = ops->mode_bits; | 1182 | master->mode_bits = ops->mode_bits; |
1183 | master->flags = ops->flags; | ||
1200 | master->dev.of_node = pdev->dev.of_node; | 1184 | master->dev.of_node = pdev->dev.of_node; |
1201 | 1185 | ||
1202 | ret = platform_get_irq_byname(pdev, "rx"); | 1186 | ret = platform_get_irq_byname(pdev, "rx"); |