|
@@ -1145,19 +1145,46 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan,
|
|
|
struct rcar_dmac_desc *desc = chan->desc.running;
|
|
|
struct rcar_dmac_xfer_chunk *running = NULL;
|
|
|
struct rcar_dmac_xfer_chunk *chunk;
|
|
|
+ enum dma_status status;
|
|
|
unsigned int residue = 0;
|
|
|
unsigned int dptr = 0;
|
|
|
|
|
|
if (!desc)
|
|
|
return 0;
|
|
|
|
|
|
+ /*
|
|
|
+ * If the cookie corresponds to a descriptor that has been completed
|
|
|
+ * there is no residue. The same check has already been performed by the
|
|
|
+ * caller but without holding the channel lock, so the descriptor could
|
|
|
+ * now be complete.
|
|
|
+ */
|
|
|
+ status = dma_cookie_status(&chan->chan, cookie, NULL);
|
|
|
+ if (status == DMA_COMPLETE)
|
|
|
+ return 0;
|
|
|
+
|
|
|
/*
|
|
|
* If the cookie doesn't correspond to the currently running transfer
|
|
|
* then the descriptor hasn't been processed yet, and the residue is
|
|
|
* equal to the full descriptor size.
|
|
|
*/
|
|
|
- if (cookie != desc->async_tx.cookie)
|
|
|
- return desc->size;
|
|
|
+ if (cookie != desc->async_tx.cookie) {
|
|
|
+ list_for_each_entry(desc, &chan->desc.pending, node) {
|
|
|
+ if (cookie == desc->async_tx.cookie)
|
|
|
+ return desc->size;
|
|
|
+ }
|
|
|
+ list_for_each_entry(desc, &chan->desc.active, node) {
|
|
|
+ if (cookie == desc->async_tx.cookie)
|
|
|
+ return desc->size;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * No descriptor found for the cookie, there's thus no residue.
|
|
|
+ * This shouldn't happen if the calling driver passes a correct
|
|
|
+ * cookie value.
|
|
|
+ */
|
|
|
+ WARN(1, "No descriptor for cookie!");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* In descriptor mode the descriptor running pointer is not maintained
|