Skip to content

Commit fd0e1d8

Browse files
Jan Kuligavinodkoul
authored andcommitted
dmaengine: xilinx: xdma: Add transfer error reporting
Extend the capability of transfer status reporting. Introduce error flag, which allows to report error in case of a interrupt-reported error condition. Signed-off-by: Jan Kuliga <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent d0f22a3 commit fd0e1d8

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

drivers/dma/xilinx/xdma.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct xdma_chan {
8585
* @cyclic: Cyclic transfer vs. scatter-gather
8686
* @periods: Number of periods in the cyclic transfer
8787
* @period_size: Size of a period in bytes in cyclic transfers
88+
* @error: tx error flag
8889
*/
8990
struct xdma_desc {
9091
struct virt_dma_desc vdesc;
@@ -97,6 +98,7 @@ struct xdma_desc {
9798
bool cyclic;
9899
u32 periods;
99100
u32 period_size;
101+
bool error;
100102
};
101103

102104
#define XDMA_DEV_STATUS_REG_DMA BIT(0)
@@ -274,6 +276,7 @@ xdma_alloc_desc(struct xdma_chan *chan, u32 desc_num, bool cyclic)
274276
sw_desc->chan = chan;
275277
sw_desc->desc_num = desc_num;
276278
sw_desc->cyclic = cyclic;
279+
sw_desc->error = false;
277280
dblk_num = DIV_ROUND_UP(desc_num, XDMA_DESC_ADJACENT);
278281
sw_desc->desc_blocks = kcalloc(dblk_num, sizeof(*sw_desc->desc_blocks),
279282
GFP_NOWAIT);
@@ -769,20 +772,20 @@ static enum dma_status xdma_tx_status(struct dma_chan *chan, dma_cookie_t cookie
769772
spin_lock_irqsave(&xdma_chan->vchan.lock, flags);
770773

771774
vd = vchan_find_desc(&xdma_chan->vchan, cookie);
772-
if (vd)
773-
desc = to_xdma_desc(vd);
774-
if (!desc || !desc->cyclic) {
775-
spin_unlock_irqrestore(&xdma_chan->vchan.lock, flags);
776-
return ret;
777-
}
778-
779-
period_idx = desc->completed_desc_num % desc->periods;
780-
residue = (desc->periods - period_idx) * desc->period_size;
775+
if (!vd)
776+
goto out;
781777

778+
desc = to_xdma_desc(vd);
779+
if (desc->error) {
780+
ret = DMA_ERROR;
781+
} else if (desc->cyclic) {
782+
period_idx = desc->completed_desc_num % desc->periods;
783+
residue = (desc->periods - period_idx) * desc->period_size;
784+
dma_set_residue(state, residue);
785+
}
786+
out:
782787
spin_unlock_irqrestore(&xdma_chan->vchan.lock, flags);
783788

784-
dma_set_residue(state, residue);
785-
786789
return ret;
787790
}
788791

@@ -819,6 +822,7 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id)
819822
st &= XDMA_CHAN_STATUS_MASK;
820823
if ((st & XDMA_CHAN_ERROR_MASK) ||
821824
!(st & (CHAN_CTRL_IE_DESC_COMPLETED | CHAN_CTRL_IE_DESC_STOPPED))) {
825+
desc->error = true;
822826
xdma_err(xdev, "channel error, status register value: 0x%x", st);
823827
goto out;
824828
}

0 commit comments

Comments
 (0)