summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-pxa2xx-dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-pxa2xx-dma.c')
-rw-r--r--drivers/spi/spi-pxa2xx-dma.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c
index 5d0d8fe07966..2fa7f4b43492 100644
--- a/drivers/spi/spi-pxa2xx-dma.c
+++ b/drivers/spi/spi-pxa2xx-dma.c
@@ -51,19 +51,15 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,
51 if (!pxa25x_ssp_comp(drv_data)) 51 if (!pxa25x_ssp_comp(drv_data))
52 pxa2xx_spi_write(drv_data, SSTO, 0); 52 pxa2xx_spi_write(drv_data, SSTO, 0);
53 53
54 if (!error) { 54 if (error) {
55 msg->actual_length += drv_data->len;
56 msg->state = pxa2xx_spi_next_transfer(drv_data);
57 } else {
58 /* In case we got an error we disable the SSP now */ 55 /* In case we got an error we disable the SSP now */
59 pxa2xx_spi_write(drv_data, SSCR0, 56 pxa2xx_spi_write(drv_data, SSCR0,
60 pxa2xx_spi_read(drv_data, SSCR0) 57 pxa2xx_spi_read(drv_data, SSCR0)
61 & ~SSCR0_SSE); 58 & ~SSCR0_SSE);
62 59 msg->status = -EIO;
63 msg->state = ERROR_STATE;
64 } 60 }
65 61
66 tasklet_schedule(&drv_data->pump_transfers); 62 spi_finalize_current_transfer(drv_data->master);
67 } 63 }
68} 64}
69 65
@@ -74,11 +70,11 @@ static void pxa2xx_spi_dma_callback(void *data)
74 70
75static struct dma_async_tx_descriptor * 71static struct dma_async_tx_descriptor *
76pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, 72pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
77 enum dma_transfer_direction dir) 73 enum dma_transfer_direction dir,
74 struct spi_transfer *xfer)
78{ 75{
79 struct chip_data *chip = 76 struct chip_data *chip =
80 spi_get_ctldata(drv_data->master->cur_msg->spi); 77 spi_get_ctldata(drv_data->master->cur_msg->spi);
81 struct spi_transfer *xfer = drv_data->cur_transfer;
82 enum dma_slave_buswidth width; 78 enum dma_slave_buswidth width;
83 struct dma_slave_config cfg; 79 struct dma_slave_config cfg;
84 struct dma_chan *chan; 80 struct dma_chan *chan;
@@ -144,12 +140,13 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data)
144 return IRQ_NONE; 140 return IRQ_NONE;
145} 141}
146 142
147int pxa2xx_spi_dma_prepare(struct driver_data *drv_data) 143int pxa2xx_spi_dma_prepare(struct driver_data *drv_data,
144 struct spi_transfer *xfer)
148{ 145{
149 struct dma_async_tx_descriptor *tx_desc, *rx_desc; 146 struct dma_async_tx_descriptor *tx_desc, *rx_desc;
150 int err; 147 int err;
151 148
152 tx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_MEM_TO_DEV); 149 tx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_MEM_TO_DEV, xfer);
153 if (!tx_desc) { 150 if (!tx_desc) {
154 dev_err(&drv_data->pdev->dev, 151 dev_err(&drv_data->pdev->dev,
155 "failed to get DMA TX descriptor\n"); 152 "failed to get DMA TX descriptor\n");
@@ -157,7 +154,7 @@ int pxa2xx_spi_dma_prepare(struct driver_data *drv_data)
157 goto err_tx; 154 goto err_tx;
158 } 155 }
159 156
160 rx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_DEV_TO_MEM); 157 rx_desc = pxa2xx_spi_dma_prepare_one(drv_data, DMA_DEV_TO_MEM, xfer);
161 if (!rx_desc) { 158 if (!rx_desc) {
162 dev_err(&drv_data->pdev->dev, 159 dev_err(&drv_data->pdev->dev,
163 "failed to get DMA RX descriptor\n"); 160 "failed to get DMA RX descriptor\n");
@@ -187,6 +184,13 @@ void pxa2xx_spi_dma_start(struct driver_data *drv_data)
187 atomic_set(&drv_data->dma_running, 1); 184 atomic_set(&drv_data->dma_running, 1);
188} 185}
189 186
187void pxa2xx_spi_dma_stop(struct driver_data *drv_data)
188{
189 atomic_set(&drv_data->dma_running, 0);
190 dmaengine_terminate_sync(drv_data->master->dma_rx);
191 dmaengine_terminate_sync(drv_data->master->dma_tx);
192}
193
190int pxa2xx_spi_dma_setup(struct driver_data *drv_data) 194int pxa2xx_spi_dma_setup(struct driver_data *drv_data)
191{ 195{
192 struct pxa2xx_spi_master *pdata = drv_data->master_info; 196 struct pxa2xx_spi_master *pdata = drv_data->master_info;