struct davinci_spi_dma {
int dma_tx_channel;
int dma_rx_channel;
+ int dummy_param_slot;
enum dma_event_q eventq;
struct completion dma_tx_completion;
param.src_dst_cidx = 0;
param.ccnt = 1;
edma_write_slot(davinci_spi_dma->dma_tx_channel, ¶m);
+ edma_link(davinci_spi_dma->dma_tx_channel,
+ davinci_spi_dma->dummy_param_slot);
/*
* Receive DMA setup
davinci_spi_dma->eventq);
if (r < 0) {
pr_err("Unable to request DMA channel for SPI RX\n");
- return -EAGAIN;
+ r = -EAGAIN;
+ goto rx_dma_failed;
}
r = edma_alloc_channel(davinci_spi_dma->dma_tx_channel,
davinci_spi_dma_tx_callback, davinci_spi_dma,
davinci_spi_dma->eventq);
if (r < 0) {
- edma_free_channel(davinci_spi_dma->dma_rx_channel);
pr_err("Unable to request DMA channel for SPI TX\n");
- return -EAGAIN;
+ r = -EAGAIN;
+ goto tx_dma_failed;
}
+ r = edma_alloc_slot(EDMA_CTLR(davinci_spi_dma->dma_tx_channel),
+ EDMA_SLOT_ANY);
+ if (r < 0) {
+ pr_err("Unable to request SPI TX DMA param slot\n");
+ r = -EAGAIN;
+ goto param_failed;
+ }
+ davinci_spi_dma->dummy_param_slot = r;
+ edma_link(davinci_spi_dma->dummy_param_slot,
+ davinci_spi_dma->dummy_param_slot);
+
return 0;
+param_failed:
+ edma_free_channel(davinci_spi_dma->dma_tx_channel);
+tx_dma_failed:
+ edma_free_channel(davinci_spi_dma->dma_rx_channel);
+rx_dma_failed:
+ return r;
}
/**
free_dma:
edma_free_channel(davinci_spi->dma_channels.dma_tx_channel);
edma_free_channel(davinci_spi->dma_channels.dma_rx_channel);
+ edma_free_slot(davinci_spi->dma_channels.dummy_param_slot);
free_clk:
clk_disable(davinci_spi->clk);
clk_put(davinci_spi->clk);