diff options
| author | Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 2017-05-05 05:57:48 -0400 |
|---|---|---|
| committer | Vinod Koul <vinod.koul@intel.com> | 2017-05-14 08:54:43 -0400 |
| commit | 44d5887a8bf1e86915c8ff647337cb138149da82 (patch) | |
| tree | 06c11d68ea2a2bd13fe6a88a23c5f3d62222c886 | |
| parent | ab2c5f0a77fe49bdb6e307b397496373cb47d2c2 (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.c | 22 |
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 | */ | ||
| 219 | static 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 | */ |
| 231 | static void mv_xor_v2_add_desc_to_desq(struct mv_xor_v2_device *xor_dev, | 220 | static 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) | |||
| 306 | static dma_cookie_t | 295 | static dma_cookie_t |
| 307 | mv_xor_v2_tx_submit(struct dma_async_tx_descriptor *tx) | 296 | mv_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 | ||
