summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRobin Gong <b38343@freescale.com>2015-03-31 15:20:13 +0800
committerguoyin.chen <guoyin.chen@freescale.com>2015-05-08 17:24:34 +0800
commit29770bf28c1f6e89c493a6df815122813b705621 (patch)
treeda5e99f0a4a5997086269c6fde97680883fe895b /drivers
parent6c13a85e79cb4ddaa0a5a365e297fb051c19d8cb (diff)
MLK-10502-1 spi: spi-imx: add bits_per_word checking in dma mode
Before, hardcode buswidth as 1byte while config dma channel. Correct it to dynamically config per buswidth setting. This patch cherry-pick from v3.10.y ccf74d50f7f85b6606d06a0245a72d22601ac9d8 Signed-off-by: Robin Gong <b38343@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/spi/spi-imx.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index f09739a76210..f9ad2713a613 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -112,6 +112,8 @@ struct spi_imx_data {
u32 rxt_wml;
struct completion dma_rx_completion;
struct completion dma_tx_completion;
+ struct dma_slave_config rx_config;
+ struct dma_slave_config tx_config;
const struct spi_imx_devtype_data *devtype_data;
int chipselect[0];
@@ -762,6 +764,7 @@ static int spi_imx_setupxfer(struct spi_device *spi,
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
struct spi_imx_config config;
+ int ret;
config.bpw = t ? t->bits_per_word : spi->bits_per_word;
config.speed_hz = t ? t->speed_hz : spi->max_speed_hz;
@@ -777,12 +780,35 @@ static int spi_imx_setupxfer(struct spi_device *spi,
if (config.bpw <= 8) {
spi_imx->rx = spi_imx_buf_rx_u8;
spi_imx->tx = spi_imx_buf_tx_u8;
+ spi_imx->tx_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ spi_imx->rx_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
} else if (config.bpw <= 16) {
spi_imx->rx = spi_imx_buf_rx_u16;
spi_imx->tx = spi_imx_buf_tx_u16;
+ spi_imx->tx_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ spi_imx->rx_config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
} else {
spi_imx->rx = spi_imx_buf_rx_u32;
spi_imx->tx = spi_imx_buf_tx_u32;
+ spi_imx->tx_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ spi_imx->rx_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ }
+
+ if (spi_imx->bitbang.master->can_dma &&
+ spi_imx_can_dma(spi_imx->bitbang.master, spi, t)) {
+ ret = dmaengine_slave_config(spi_imx->bitbang.master->dma_tx,
+ &spi_imx->tx_config);
+ if (ret) {
+ dev_err(&spi->dev, "error in TX dma configuration.\n");
+ return ret;
+ }
+
+ ret = dmaengine_slave_config(spi_imx->bitbang.master->dma_rx,
+ &spi_imx->rx_config);
+ if (ret) {
+ dev_err(&spi->dev, "error in RX dma configuration.\n");
+ return ret;
+ }
}
spi_imx->devtype_data->config(spi_imx, &config);
@@ -811,7 +837,6 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx,
struct spi_master *master,
const struct resource *res)
{
- struct dma_slave_config slave_config = {};
int ret;
/* Prepare for TX DMA: */
@@ -822,11 +847,11 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx,
goto err;
}
- slave_config.direction = DMA_MEM_TO_DEV;
- slave_config.dst_addr = res->start + MXC_CSPITXDATA;
- slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
- slave_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) / 4;
- ret = dmaengine_slave_config(master->dma_tx, &slave_config);
+ spi_imx->tx_config.direction = DMA_MEM_TO_DEV;
+ spi_imx->tx_config.dst_addr = res->start + MXC_CSPITXDATA;
+ spi_imx->tx_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ spi_imx->tx_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) / 4;
+ ret = dmaengine_slave_config(master->dma_tx, &spi_imx->tx_config);
if (ret) {
dev_err(dev, "error in TX dma configuration.\n");
goto err;
@@ -840,11 +865,11 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx,
goto err;
}
- slave_config.direction = DMA_DEV_TO_MEM;
- slave_config.src_addr = res->start + MXC_CSPIRXDATA;
- slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
- slave_config.src_maxburst = spi_imx_get_fifosize(spi_imx) / 2;
- ret = dmaengine_slave_config(master->dma_rx, &slave_config);
+ spi_imx->rx_config.direction = DMA_DEV_TO_MEM;
+ spi_imx->rx_config.src_addr = res->start + MXC_CSPIRXDATA;
+ spi_imx->rx_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ spi_imx->rx_config.src_maxburst = spi_imx_get_fifosize(spi_imx) / 2;
+ ret = dmaengine_slave_config(master->dma_rx, &spi_imx->rx_config);
if (ret) {
dev_err(dev, "error in RX dma configuration.\n");
goto err;
@@ -1005,6 +1030,7 @@ static int spi_imx_transfer(struct spi_device *spi,
spi_imx_can_dma(spi_imx->bitbang.master, spi, transfer)) {
spi_imx->usedma = true;
ret = spi_imx_dma_transfer(spi_imx, transfer);
+ spi_imx->usedma = false; /* clear the dma flag */
if (ret != -EAGAIN)
return ret;
}