aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2017-05-05 05:57:48 -0400
committerVinod Koul <vinod.koul@intel.com>2017-05-14 08:54:43 -0400
commit44d5887a8bf1e86915c8ff647337cb138149da82 (patch)
tree06c11d68ea2a2bd13fe6a88a23c5f3d62222c886
parentab2c5f0a77fe49bdb6e307b397496373cb47d2c2 (diff)
dmaengine: mv_xor_v2: fix tx_submit() implementation
The mv_xor_v2_tx_submit() gets the next available HW descriptor by calling mv_xor_v2_get_desq_write_ptr(), which reads a HW register telling the next available HW descriptor. This was working fine when HW descriptors were issued for processing directly in tx_submit(). However, as part of the review process of the driver, a change was requested to move the actual kick-off of HW descriptors processing to ->issue_pending(). Due to this, reading the HW register to know the next available HW descriptor no longer works. So instead of using this HW register, we implemented a software index pointing to the next available HW descriptor. Fixes: 19a340b1a820 ("dmaengine: mv_xor_v2: new driver") Cc: <stable@vger.kernel.org> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r--drivers/dma/mv_xor_v2.c22
1 files changed, 5 insertions, 17 deletions
diff --git a/drivers/dma/mv_xor_v2.c b/drivers/dma/mv_xor_v2.c
index 211b8c0e3cfb..4684eceea759 100644
--- a/drivers/dma/mv_xor_v2.c
+++ b/drivers/dma/mv_xor_v2.c
@@ -161,6 +161,7 @@ struct mv_xor_v2_device {
161 struct mv_xor_v2_sw_desc *sw_desq; 161 struct mv_xor_v2_sw_desc *sw_desq;
162 int desc_size; 162 int desc_size;
163 unsigned int npendings; 163 unsigned int npendings;
164 unsigned int hw_queue_idx;
164}; 165};
165 166
166/** 167/**
@@ -214,18 +215,6 @@ static void mv_xor_v2_set_data_buffers(struct mv_xor_v2_device *xor_dev,
214} 215}
215 216
216/* 217/*
217 * Return the next available index in the DESQ.
218 */
219static int mv_xor_v2_get_desq_write_ptr(struct mv_xor_v2_device *xor_dev)
220{
221 /* read the index for the next available descriptor in the DESQ */
222 u32 reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_ALLOC_OFF);
223
224 return ((reg >> MV_XOR_V2_DMA_DESQ_ALLOC_WRPTR_SHIFT)
225 & MV_XOR_V2_DMA_DESQ_ALLOC_WRPTR_MASK);
226}
227
228/*
229 * notify the engine of new descriptors, and update the available index. 218 * notify the engine of new descriptors, and update the available index.
230 */ 219 */
231static void mv_xor_v2_add_desc_to_desq(struct mv_xor_v2_device *xor_dev, 220static void mv_xor_v2_add_desc_to_desq(struct mv_xor_v2_device *xor_dev,
@@ -306,7 +295,6 @@ static irqreturn_t mv_xor_v2_interrupt_handler(int irq, void *data)
306static dma_cookie_t 295static dma_cookie_t
307mv_xor_v2_tx_submit(struct dma_async_tx_descriptor *tx) 296mv_xor_v2_tx_submit(struct dma_async_tx_descriptor *tx)
308{ 297{
309 int desq_ptr;
310 void *dest_hw_desc; 298 void *dest_hw_desc;
311 dma_cookie_t cookie; 299 dma_cookie_t cookie;
312 struct mv_xor_v2_sw_desc *sw_desc = 300 struct mv_xor_v2_sw_desc *sw_desc =
@@ -322,15 +310,15 @@ mv_xor_v2_tx_submit(struct dma_async_tx_descriptor *tx)
322 spin_lock_bh(&xor_dev->lock); 310 spin_lock_bh(&xor_dev->lock);
323 cookie = dma_cookie_assign(tx); 311 cookie = dma_cookie_assign(tx);
324 312
325 /* get the next available slot in the DESQ */
326 desq_ptr = mv_xor_v2_get_desq_write_ptr(xor_dev);
327
328 /* copy the HW descriptor from the SW descriptor to the DESQ */ 313 /* copy the HW descriptor from the SW descriptor to the DESQ */
329 dest_hw_desc = xor_dev->hw_desq_virt + desq_ptr; 314 dest_hw_desc = xor_dev->hw_desq_virt + xor_dev->hw_queue_idx;
330 315
331 memcpy(dest_hw_desc, &sw_desc->hw_desc, xor_dev->desc_size); 316 memcpy(dest_hw_desc, &sw_desc->hw_desc, xor_dev->desc_size);
332 317
333 xor_dev->npendings++; 318 xor_dev->npendings++;
319 xor_dev->hw_queue_idx++;
320 if (xor_dev->hw_queue_idx >= MV_XOR_V2_DESC_NUM)
321 xor_dev->hw_queue_idx = 0;
334 322
335 spin_unlock_bh(&xor_dev->lock); 323 spin_unlock_bh(&xor_dev->lock);
336 324