X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=target%2Flinux%2Fpistachio%2Fpatches-6.1%2F101-dmaengine-img-mdc-Handle-early-status-read.patch;fp=target%2Flinux%2Fpistachio%2Fpatches-6.1%2F101-dmaengine-img-mdc-Handle-early-status-read.patch;h=031a4e3e5eedd65a431de80a6d1e57e1c415e444;hp=0000000000000000000000000000000000000000;hb=05fe149486af7c02d69410df04875a0a824d1d9b;hpb=63dd14b906e9eb27bc878b95ac6777a3624b1135 diff --git a/target/linux/pistachio/patches-6.1/101-dmaengine-img-mdc-Handle-early-status-read.patch b/target/linux/pistachio/patches-6.1/101-dmaengine-img-mdc-Handle-early-status-read.patch new file mode 100644 index 0000000000..031a4e3e5e --- /dev/null +++ b/target/linux/pistachio/patches-6.1/101-dmaengine-img-mdc-Handle-early-status-read.patch @@ -0,0 +1,68 @@ +From a2dd154377c9aa6ddda00d39b8c7c334e4fa16ff Mon Sep 17 00:00:00 2001 +From: Damien Horsley +Date: Tue, 22 Mar 2016 12:46:09 +0000 +Subject: dmaengine: img-mdc: Handle early status read + +It is possible that mdc_tx_status may be called before the first +node has been read from memory. + +In this case, the residue value stored in the register is undefined. +Return the transfer size instead. + +Signed-off-by: Damien Horsley +--- + drivers/dma/img-mdc-dma.c | 40 ++++++++++++++++++++++++---------------- + 1 file changed, 24 insertions(+), 16 deletions(-) + +--- a/drivers/dma/img-mdc-dma.c ++++ b/drivers/dma/img-mdc-dma.c +@@ -618,25 +618,33 @@ static enum dma_status mdc_tx_status(str + (MDC_CMDS_PROCESSED_CMDS_DONE_MASK + 1); + + /* +- * If the command loaded event hasn't been processed yet, then +- * the difference above includes an extra command. ++ * If the first node has not yet been read from memory, ++ * the residue register value is undefined + */ +- if (!mdesc->cmd_loaded) +- cmds--; +- else +- cmds += mdesc->list_cmds_done; +- +- bytes = mdesc->list_xfer_size; +- ldesc = mdesc->list; +- for (i = 0; i < cmds; i++) { +- bytes -= ldesc->xfer_size + 1; +- ldesc = ldesc->next_desc; +- } +- if (ldesc) { +- if (residue != MDC_TRANSFER_SIZE_MASK) +- bytes -= ldesc->xfer_size - residue; ++ if (!mdesc->cmd_loaded && !cmds) { ++ bytes = mdesc->list_xfer_size; ++ } else { ++ /* ++ * If the command loaded event hasn't been processed yet, then ++ * the difference above includes an extra command. ++ */ ++ if (!mdesc->cmd_loaded) ++ cmds--; + else ++ cmds += mdesc->list_cmds_done; ++ ++ bytes = mdesc->list_xfer_size; ++ ldesc = mdesc->list; ++ for (i = 0; i < cmds; i++) { + bytes -= ldesc->xfer_size + 1; ++ ldesc = ldesc->next_desc; ++ } ++ if (ldesc) { ++ if (residue != MDC_TRANSFER_SIZE_MASK) ++ bytes -= ldesc->xfer_size - residue; ++ else ++ bytes -= ldesc->xfer_size + 1; ++ } + } + } + spin_unlock_irqrestore(&mchan->vc.lock, flags);