aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorBrian Niebuhr <bniebuhr@efjohnson.com>2010-10-04 08:05:34 -0400
committerSekhar Nori <nsekhar@ti.com>2010-11-18 08:08:35 -0500
commit523c37e7006522e778a1fd0aea2746ceb788572f (patch)
treecc2146d573961b5cb62615c136042a88984c842a /drivers/spi
parent903ca25b219e28e3513ca4c2ff379fcdf19e057e (diff)
spi: davinci: fix EDMA CC errors at end of transfers
Use a dummy param slot linked to itself to take care of the extra "sync event" that gets sent to EDMA controller after the last byte has been transferred. The dummy PaRAM slot that is linked to the actual DMA PaRAM slot "absorbs" this event and prevents a EDMA CC error to be asserted. Without this provision, the EDMA CC error would be asserted because the channel PaRAM would be empty after the transfer and EDMA would not know what to make out of the extra sync event. 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')
-rw-r--r--drivers/spi/davinci_spi.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 6db478601024..975c2a228d0a 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -116,6 +116,7 @@
116struct davinci_spi_dma { 116struct davinci_spi_dma {
117 int dma_tx_channel; 117 int dma_tx_channel;
118 int dma_rx_channel; 118 int dma_rx_channel;
119 int dummy_param_slot;
119 enum dma_event_q eventq; 120 enum dma_event_q eventq;
120 121
121 struct completion dma_tx_completion; 122 struct completion dma_tx_completion;
@@ -697,6 +698,8 @@ static int davinci_spi_bufs_dma(struct spi_device *spi, struct spi_transfer *t)
697 param.src_dst_cidx = 0; 698 param.src_dst_cidx = 0;
698 param.ccnt = 1; 699 param.ccnt = 1;
699 edma_write_slot(davinci_spi_dma->dma_tx_channel, &param); 700 edma_write_slot(davinci_spi_dma->dma_tx_channel, &param);
701 edma_link(davinci_spi_dma->dma_tx_channel,
702 davinci_spi_dma->dummy_param_slot);
700 703
701 /* 704 /*
702 * Receive DMA setup 705 * Receive DMA setup
@@ -779,19 +782,37 @@ static int davinci_spi_request_dma(struct davinci_spi_dma *davinci_spi_dma)
779 davinci_spi_dma->eventq); 782 davinci_spi_dma->eventq);
780 if (r < 0) { 783 if (r < 0) {
781 pr_err("Unable to request DMA channel for SPI RX\n"); 784 pr_err("Unable to request DMA channel for SPI RX\n");
782 return -EAGAIN; 785 r = -EAGAIN;
786 goto rx_dma_failed;
783 } 787 }
784 788
785 r = edma_alloc_channel(davinci_spi_dma->dma_tx_channel, 789 r = edma_alloc_channel(davinci_spi_dma->dma_tx_channel,
786 davinci_spi_dma_tx_callback, davinci_spi_dma, 790 davinci_spi_dma_tx_callback, davinci_spi_dma,
787 davinci_spi_dma->eventq); 791 davinci_spi_dma->eventq);
788 if (r < 0) { 792 if (r < 0) {
789 edma_free_channel(davinci_spi_dma->dma_rx_channel);
790 pr_err("Unable to request DMA channel for SPI TX\n"); 793 pr_err("Unable to request DMA channel for SPI TX\n");
791 return -EAGAIN; 794 r = -EAGAIN;
795 goto tx_dma_failed;
792 } 796 }
793 797
798 r = edma_alloc_slot(EDMA_CTLR(davinci_spi_dma->dma_tx_channel),
799 EDMA_SLOT_ANY);
800 if (r < 0) {
801 pr_err("Unable to request SPI TX DMA param slot\n");
802 r = -EAGAIN;
803 goto param_failed;
804 }
805 davinci_spi_dma->dummy_param_slot = r;
806 edma_link(davinci_spi_dma->dummy_param_slot,
807 davinci_spi_dma->dummy_param_slot);
808
794 return 0; 809 return 0;
810param_failed:
811 edma_free_channel(davinci_spi_dma->dma_tx_channel);
812tx_dma_failed:
813 edma_free_channel(davinci_spi_dma->dma_rx_channel);
814rx_dma_failed:
815 return r;
795} 816}
796 817
797/** 818/**
@@ -970,6 +991,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
970free_dma: 991free_dma:
971 edma_free_channel(davinci_spi->dma_channels.dma_tx_channel); 992 edma_free_channel(davinci_spi->dma_channels.dma_tx_channel);
972 edma_free_channel(davinci_spi->dma_channels.dma_rx_channel); 993 edma_free_channel(davinci_spi->dma_channels.dma_rx_channel);
994 edma_free_slot(davinci_spi->dma_channels.dummy_param_slot);
973free_clk: 995free_clk:
974 clk_disable(davinci_spi->clk); 996 clk_disable(davinci_spi->clk);
975 clk_put(davinci_spi->clk); 997 clk_put(davinci_spi->clk);