dmaengine fixes for 4.5
Few more late fixes on drivers nothing major here. - A memory leak fix in fsdma unmap the dma descriptors on freeup. - A fix in xdmac driver for residue calculation of dma descriptor. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJW4vAbAAoJEHwUBw8lI4NHc1kP/14BOZIWPRs7q/Hv/u4nOkz+ feTa0Fv744GO1MaiQAqZo2qTqJ1scp+b29J9xjkN+pLogQ0H6bxCJa0XP843eb91 kurLq24p9OQ4u+RaW84WB8TWEpCC+YjfThm5R2N320R9rqt+waSGw6FEk/tL61Iu TIAo+nipLxNFr3ctBvzqJjIdclQ7X9b1WL6cc6nnNZtDXb4e+hwzlP2l7e2XFuRu 7UEN1hyvqNKEh8TMi6ix9Wtae+XIY9DDEc3f8lGE0lkzwAEFXYKO1J3zRHyjnNMy fCWMIb0pXkXy2as3fmJ7RQ+AvWnSpNHSE0e5R3fmWWsM1ztFM3VgdrThNBRu27vL DJn/eVFfa7rItSJTyBKijykkMHrjgXXyhdkQqnXLwl2+aURZfmsvH6ZAhBfHWody io3VA5wZJmJqSZ3I/pIDwoEAwvukusic8ArJplry4W6TFn1+tQXcgz+rL6ATp/Wt gt6+5mSJqH/JkUJMS41MU1FKGlDSKSF5V8pgg7I0yByU8E51c8cqhA04ZlFVG2BO RE0ZDFg0fHCZkcXn7u7xE1ye9FuhdY/BpRLsvGcfhcByr3HXYbrXkQsX/AOKM3uC epE/pViMhWXx6bATYTl0Polg5qaIVwXPcYv3gx/4fL963lz1jbC4uVzgtSCJi7an HjrnmH5UbX0PtNRoU9VQ =Y4sQ -----END PGP SIGNATURE----- Merge tag 'dmaengine-fix-4.5' of git://git.infradead.org/users/vkoul/slave-dma Pull dmaengine fixes from Vinod Koul: "Two fixes showed up in last few days, and they should be included in 4.5. Summary: Two more late fixes to drivers, nothing major here: - A memory leak fix in fsdma unmap the dma descriptors on freeup - A fix in xdmac driver for residue calculation of dma descriptor" * tag 'dmaengine-fix-4.5' of git://git.infradead.org/users/vkoul/slave-dma: dmaengine: at_xdmac: fix residue computation dmaengine: fsldma: fix memory leak
This commit is contained in:
commit
20698c922f
|
@ -176,6 +176,7 @@
|
|||
#define AT_XDMAC_MAX_CHAN 0x20
|
||||
#define AT_XDMAC_MAX_CSIZE 16 /* 16 data */
|
||||
#define AT_XDMAC_MAX_DWIDTH 8 /* 64 bits */
|
||||
#define AT_XDMAC_RESIDUE_MAX_RETRIES 5
|
||||
|
||||
#define AT_XDMAC_DMA_BUSWIDTHS\
|
||||
(BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\
|
||||
|
@ -1395,8 +1396,8 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
|
|||
struct at_xdmac_desc *desc, *_desc;
|
||||
struct list_head *descs_list;
|
||||
enum dma_status ret;
|
||||
int residue;
|
||||
u32 cur_nda, mask, value;
|
||||
int residue, retry;
|
||||
u32 cur_nda, check_nda, cur_ubc, mask, value;
|
||||
u8 dwidth = 0;
|
||||
unsigned long flags;
|
||||
|
||||
|
@ -1433,7 +1434,42 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
|
|||
cpu_relax();
|
||||
}
|
||||
|
||||
/*
|
||||
* When processing the residue, we need to read two registers but we
|
||||
* can't do it in an atomic way. AT_XDMAC_CNDA is used to find where
|
||||
* we stand in the descriptor list and AT_XDMAC_CUBC is used
|
||||
* to know how many data are remaining for the current descriptor.
|
||||
* Since the dma channel is not paused to not loose data, between the
|
||||
* AT_XDMAC_CNDA and AT_XDMAC_CUBC read, we may have change of
|
||||
* descriptor.
|
||||
* For that reason, after reading AT_XDMAC_CUBC, we check if we are
|
||||
* still using the same descriptor by reading a second time
|
||||
* AT_XDMAC_CNDA. If AT_XDMAC_CNDA has changed, it means we have to
|
||||
* read again AT_XDMAC_CUBC.
|
||||
* Memory barriers are used to ensure the read order of the registers.
|
||||
* A max number of retries is set because unlikely it can never ends if
|
||||
* we are transferring a lot of data with small buffers.
|
||||
*/
|
||||
cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
|
||||
rmb();
|
||||
cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC);
|
||||
for (retry = 0; retry < AT_XDMAC_RESIDUE_MAX_RETRIES; retry++) {
|
||||
rmb();
|
||||
check_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
|
||||
|
||||
if (likely(cur_nda == check_nda))
|
||||
break;
|
||||
|
||||
cur_nda = check_nda;
|
||||
rmb();
|
||||
cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC);
|
||||
}
|
||||
|
||||
if (unlikely(retry >= AT_XDMAC_RESIDUE_MAX_RETRIES)) {
|
||||
ret = DMA_ERROR;
|
||||
goto spin_unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove size of all microblocks already transferred and the current
|
||||
* one. Then add the remaining size to transfer of the current
|
||||
|
@ -1446,7 +1482,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
|
|||
if ((desc->lld.mbr_nda & 0xfffffffc) == cur_nda)
|
||||
break;
|
||||
}
|
||||
residue += at_xdmac_chan_read(atchan, AT_XDMAC_CUBC) << dwidth;
|
||||
residue += cur_ubc << dwidth;
|
||||
|
||||
dma_set_residue(txstate, residue);
|
||||
|
||||
|
|
|
@ -522,6 +522,8 @@ static dma_cookie_t fsldma_run_tx_complete_actions(struct fsldma_chan *chan,
|
|||
chan_dbg(chan, "LD %p callback\n", desc);
|
||||
txd->callback(txd->callback_param);
|
||||
}
|
||||
|
||||
dma_descriptor_unmap(txd);
|
||||
}
|
||||
|
||||
/* Run any dependencies */
|
||||
|
|
Loading…
Reference in New Issue