diff options
Diffstat (limited to 'drivers/spi/spi-pxa2xx-dma.c')
-rw-r--r-- | drivers/spi/spi-pxa2xx-dma.c | 28 |
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 | ||
75 | static struct dma_async_tx_descriptor * | 71 | static struct dma_async_tx_descriptor * |
76 | pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data, | 72 | pxa2xx_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 | ||
147 | int pxa2xx_spi_dma_prepare(struct driver_data *drv_data) | 143 | int 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 | ||
187 | void 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 | |||
190 | int pxa2xx_spi_dma_setup(struct driver_data *drv_data) | 194 | int 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; |