summaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2012-02-22 15:13:24 +0530
committerLokesh Pathak <lpathak@nvidia.com>2012-02-23 05:10:37 -0800
commitd15177bea60854a9f3be24992a68e3acb71eac98 (patch)
treecfc4845234f6820f69d25210a072236fdf8fddf6 /drivers/spi
parentb6dba7d7c190cc89d694b722b3ca9bc7ccb4e6d7 (diff)
spi: tegra: Add Dma/cpu buffer synchronisation
When dma coherant buffer need to be access by cpu or apb dma, it is require to calling the dma_sync_single_for_cpu() when cpu wants to access it and dma_sync_single_for_device() when dma wants to access the buffer. Change-Id: I62fc7fced782f3fc2d145c0d5416a4c8cbe30715 Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-on: http://git-master/r/85138 Reviewed-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-tegra.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c
index 7be67d0ff2bc..e757f1adfb5e 100644
--- a/drivers/spi/spi-tegra.c
+++ b/drivers/spi/spi-tegra.c
@@ -429,6 +429,10 @@ static void spi_tegra_copy_client_txbuf_to_spi_txbuf(
struct spi_tegra_data *tspi, struct spi_transfer *t)
{
unsigned len;
+
+ /* Make the dma buffer to read by cpu */
+ dma_sync_single_for_cpu(&tspi->pdev->dev, tspi->tx_buf_phys,
+ tspi->dma_buf_size, DMA_FROM_DEVICE);
if (tspi->is_packed) {
len = tspi->curr_dma_words * tspi->bytes_per_word;
memcpy(tspi->tx_buf, t->tx_buf + tspi->cur_pos, len);
@@ -448,12 +452,20 @@ static void spi_tegra_copy_client_txbuf_to_spi_txbuf(
}
}
tspi->cur_tx_pos += tspi->curr_dma_words * tspi->bytes_per_word;
+ /* Make the dma buffer to read by dma */
+ dma_sync_single_for_device(&tspi->pdev->dev, tspi->tx_buf_phys,
+ tspi->dma_buf_size, DMA_TO_DEVICE);
}
static void spi_tegra_copy_spi_rxbuf_to_client_rxbuf(
struct spi_tegra_data *tspi, struct spi_transfer *t)
{
unsigned len;
+
+ /* Make the dma buffer to read by cpu */
+ dma_sync_single_for_cpu(&tspi->pdev->dev, tspi->rx_buf_phys,
+ tspi->dma_buf_size, DMA_FROM_DEVICE);
+
if (tspi->is_packed) {
len = tspi->curr_dma_words * tspi->bytes_per_word;
memcpy(t->rx_buf + tspi->cur_rx_pos, tspi->rx_buf, len);
@@ -475,6 +487,10 @@ static void spi_tegra_copy_spi_rxbuf_to_client_rxbuf(
}
}
tspi->cur_rx_pos += tspi->curr_dma_words * tspi->bytes_per_word;
+
+ /* Make the dma buffer to read by dma */
+ dma_sync_single_for_device(&tspi->pdev->dev, tspi->rx_buf_phys,
+ tspi->dma_buf_size, DMA_TO_DEVICE);
}
static int spi_tegra_start_dma_based_transfer(
@@ -488,6 +504,13 @@ static int spi_tegra_start_dma_based_transfer(
INIT_COMPLETION(tspi->rx_dma_complete);
INIT_COMPLETION(tspi->tx_dma_complete);
+ /* Make sure that Rx and Tx fifo are empty */
+ test_val = spi_tegra_readl(tspi, SLINK_STATUS);
+ if (((test_val >> 20) & 0xF) != 0xA)
+ dev_err(&tspi->pdev->dev,
+ "The Rx and Tx fifo are not empty status 0x%08lx\n",
+ test_val);
+
val = SLINK_DMA_BLOCK_SIZE(tspi->curr_dma_words - 1);
val |= tspi->packed_size;
if (tspi->is_packed)
@@ -515,6 +538,9 @@ static int spi_tegra_start_dma_based_transfer(
if (tspi->cur_direction & DATA_DIR_TX) {
spi_tegra_copy_client_txbuf_to_spi_txbuf(tspi, t);
wmb();
+ /* Make the dma buffer to read by dma */
+ dma_sync_single_for_device(&tspi->pdev->dev, tspi->tx_buf_phys,
+ tspi->dma_buf_size, DMA_TO_DEVICE);
tspi->tx_dma_req.size = len;
ret = tegra_dma_enqueue_req(tspi->tx_dma, &tspi->tx_dma_req);
if (ret < 0) {
@@ -530,6 +556,9 @@ static int spi_tegra_start_dma_based_transfer(
}
if (tspi->cur_direction & DATA_DIR_RX) {
+ /* Make the dma buffer to read by dma */
+ dma_sync_single_for_device(&tspi->pdev->dev, tspi->rx_buf_phys,
+ tspi->dma_buf_size, DMA_TO_DEVICE);
tspi->rx_dma_req.size = len;
ret = tegra_dma_enqueue_req(tspi->rx_dma, &tspi->rx_dma_req);
if (ret < 0) {
@@ -1301,6 +1330,10 @@ static int __init spi_tegra_probe(struct platform_device *pdev)
goto fail_rx_buf_alloc;
}
+ /* Make the dma buffer to read by dma */
+ dma_sync_single_for_device(&tspi->pdev->dev, tspi->rx_buf_phys,
+ tspi->dma_buf_size, DMA_TO_DEVICE);
+
memset(&tspi->rx_dma_req, 0, sizeof(struct tegra_dma_req));
tspi->rx_dma_req.complete = tegra_spi_rx_dma_complete;
tspi->rx_dma_req.to_memory = 1;
@@ -1330,6 +1363,10 @@ static int __init spi_tegra_probe(struct platform_device *pdev)
goto fail_tx_buf_alloc;
}
+ /* Make the dma buffer to read by dma */
+ dma_sync_single_for_device(&tspi->pdev->dev, tspi->tx_buf_phys,
+ tspi->dma_buf_size, DMA_TO_DEVICE);
+
memset(&tspi->tx_dma_req, 0, sizeof(struct tegra_dma_req));
tspi->tx_dma_req.complete = tegra_spi_tx_dma_complete;
tspi->tx_dma_req.to_memory = 0;