aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/davinci_spi.c52
1 files changed, 21 insertions, 31 deletions
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index a5f03dd8d8da..f5129390bc2d 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -38,8 +38,6 @@
38 38
39#define CS_DEFAULT 0xFF 39#define CS_DEFAULT 0xFF
40 40
41#define SPI_BUFSIZ (SMP_CACHE_BYTES + 1)
42
43#define SPIFMT_PHASE_MASK BIT(16) 41#define SPIFMT_PHASE_MASK BIT(16)
44#define SPIFMT_POLARITY_MASK BIT(17) 42#define SPIFMT_POLARITY_MASK BIT(17)
45#define SPIFMT_DISTIMER_MASK BIT(18) 43#define SPIFMT_DISTIMER_MASK BIT(18)
@@ -140,7 +138,6 @@ struct davinci_spi {
140 138
141 const void *tx; 139 const void *tx;
142 void *rx; 140 void *rx;
143 u8 *tmp_buf;
144 int rcount; 141 int rcount;
145 int wcount; 142 int wcount;
146 struct davinci_spi_dma dma_channels; 143 struct davinci_spi_dma dma_channels;
@@ -718,7 +715,7 @@ static int davinci_spi_bufs_dma(struct spi_device *spi, struct spi_transfer *t)
718{ 715{
719 struct davinci_spi *davinci_spi; 716 struct davinci_spi *davinci_spi;
720 int int_status = 0; 717 int int_status = 0;
721 int count, temp_count; 718 int count;
722 struct davinci_spi_dma *davinci_spi_dma; 719 struct davinci_spi_dma *davinci_spi_dma;
723 int data_type, ret; 720 int data_type, ret;
724 unsigned long tx_reg, rx_reg; 721 unsigned long tx_reg, rx_reg;
@@ -750,6 +747,18 @@ static int davinci_spi_bufs_dma(struct spi_device *spi, struct spi_transfer *t)
750 /* Enable SPI */ 747 /* Enable SPI */
751 set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_SPIENA_MASK); 748 set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_SPIENA_MASK);
752 749
750 /*
751 * Transmit DMA setup
752 *
753 * If there is transmit data, map the transmit buffer, set it as the
754 * source of data and set the source B index to data size.
755 * If there is no transmit data, set the transmit register as the
756 * source of data, and set the source B index to zero.
757 *
758 * The destination is always the transmit register itself. And the
759 * destination never increments.
760 */
761
753 if (t->tx_buf) { 762 if (t->tx_buf) {
754 t->tx_dma = dma_map_single(&spi->dev, (void *)t->tx_buf, count, 763 t->tx_dma = dma_map_single(&spi->dev, (void *)t->tx_buf, count,
755 DMA_TO_DEVICE); 764 DMA_TO_DEVICE);
@@ -758,25 +767,15 @@ static int davinci_spi_bufs_dma(struct spi_device *spi, struct spi_transfer *t)
758 " TX buffer\n", count); 767 " TX buffer\n", count);
759 return -ENOMEM; 768 return -ENOMEM;
760 } 769 }
761 temp_count = count;
762 } else {
763 /* We need TX clocking for RX transaction */
764 t->tx_dma = dma_map_single(&spi->dev,
765 (void *)davinci_spi->tmp_buf, count + 1,
766 DMA_TO_DEVICE);
767 if (dma_mapping_error(&spi->dev, t->tx_dma)) {
768 dev_dbg(sdev, "Unable to DMA map a %d bytes"
769 " TX tmp buffer\n", count);
770 return -ENOMEM;
771 }
772 temp_count = count + 1;
773 } 770 }
774 771
775 edma_set_transfer_params(davinci_spi_dma->dma_tx_channel, 772 edma_set_transfer_params(davinci_spi_dma->dma_tx_channel,
776 data_type, temp_count, 1, 0, ASYNC); 773 data_type, count, 1, 0, ASYNC);
777 edma_set_dest(davinci_spi_dma->dma_tx_channel, tx_reg, INCR, W8BIT); 774 edma_set_dest(davinci_spi_dma->dma_tx_channel, tx_reg, INCR, W8BIT);
778 edma_set_src(davinci_spi_dma->dma_tx_channel, t->tx_dma, INCR, W8BIT); 775 edma_set_src(davinci_spi_dma->dma_tx_channel,
779 edma_set_src_index(davinci_spi_dma->dma_tx_channel, data_type, 0); 776 t->tx_buf ? t->tx_dma : tx_reg, INCR, W8BIT);
777 edma_set_src_index(davinci_spi_dma->dma_tx_channel,
778 t->tx_buf ? data_type : 0, 0);
780 edma_set_dest_index(davinci_spi_dma->dma_tx_channel, 0, 0); 779 edma_set_dest_index(davinci_spi_dma->dma_tx_channel, 0, 0);
781 780
782 if (t->rx_buf) { 781 if (t->rx_buf) {
@@ -818,7 +817,8 @@ static int davinci_spi_bufs_dma(struct spi_device *spi, struct spi_transfer *t)
818 wait_for_completion_interruptible( 817 wait_for_completion_interruptible(
819 &davinci_spi_dma->dma_rx_completion); 818 &davinci_spi_dma->dma_rx_completion);
820 819
821 dma_unmap_single(NULL, t->tx_dma, temp_count, DMA_TO_DEVICE); 820 if (t->tx_buf)
821 dma_unmap_single(NULL, t->tx_dma, count, DMA_TO_DEVICE);
822 822
823 if (t->rx_buf) 823 if (t->rx_buf)
824 dma_unmap_single(NULL, t->rx_dma, count, DMA_FROM_DEVICE); 824 dma_unmap_single(NULL, t->rx_dma, count, DMA_FROM_DEVICE);
@@ -906,17 +906,10 @@ static int davinci_spi_probe(struct platform_device *pdev)
906 if (ret) 906 if (ret)
907 goto unmap_io; 907 goto unmap_io;
908 908
909 /* Allocate tmp_buf for tx_buf */
910 davinci_spi->tmp_buf = kzalloc(SPI_BUFSIZ, GFP_KERNEL);
911 if (davinci_spi->tmp_buf == NULL) {
912 ret = -ENOMEM;
913 goto irq_free;
914 }
915
916 davinci_spi->bitbang.master = spi_master_get(master); 909 davinci_spi->bitbang.master = spi_master_get(master);
917 if (davinci_spi->bitbang.master == NULL) { 910 if (davinci_spi->bitbang.master == NULL) {
918 ret = -ENODEV; 911 ret = -ENODEV;
919 goto free_tmp_buf; 912 goto irq_free;
920 } 913 }
921 914
922 davinci_spi->clk = clk_get(&pdev->dev, NULL); 915 davinci_spi->clk = clk_get(&pdev->dev, NULL);
@@ -1027,8 +1020,6 @@ free_clk:
1027 clk_put(davinci_spi->clk); 1020 clk_put(davinci_spi->clk);
1028put_master: 1021put_master:
1029 spi_master_put(master); 1022 spi_master_put(master);
1030free_tmp_buf:
1031 kfree(davinci_spi->tmp_buf);
1032irq_free: 1023irq_free:
1033 free_irq(davinci_spi->irq, davinci_spi); 1024 free_irq(davinci_spi->irq, davinci_spi);
1034unmap_io: 1025unmap_io:
@@ -1063,7 +1054,6 @@ static int __exit davinci_spi_remove(struct platform_device *pdev)
1063 clk_disable(davinci_spi->clk); 1054 clk_disable(davinci_spi->clk);
1064 clk_put(davinci_spi->clk); 1055 clk_put(davinci_spi->clk);
1065 spi_master_put(master); 1056 spi_master_put(master);
1066 kfree(davinci_spi->tmp_buf);
1067 free_irq(davinci_spi->irq, davinci_spi); 1057 free_irq(davinci_spi->irq, davinci_spi);
1068 iounmap(davinci_spi->base); 1058 iounmap(davinci_spi->base);
1069 release_mem_region(davinci_spi->pbase, davinci_spi->region_size); 1059 release_mem_region(davinci_spi->pbase, davinci_spi->region_size);