aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/davinci_spi.c
diff options
context:
space:
mode:
authorBrian Niebuhr <bniebuhr@efjohnson.com>2010-09-29 03:01:54 -0400
committerSekhar Nori <nsekhar@ti.com>2010-11-18 08:08:33 -0500
commitd3f7141cbf4580b2f18f93940df29cf0c15e7ef5 (patch)
treeb8e168c11588653d0582db1faaa323a35bae4644 /drivers/spi/davinci_spi.c
parentc29e3c60e75d1cc1262ac8af379738b6fd851f33 (diff)
spi: davinci: do not use temporary buffer if no transmit data provided
Remove usage of temporary buffer when no transmit data is provided. Instead, use the transmit register itself as the source of data. By choosing the transmit register itself as the source of data, this patch helps remove unnecessary accesses to memory when no real data is being transmitted. Signed-off-by: Brian Niebuhr <bniebuhr@efjohnson.com> Tested-By: Michael Williamson <michael.williamson@criticallink.com> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Diffstat (limited to 'drivers/spi/davinci_spi.c')
-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);