pistachio: add 4.9 kernel support
[librecmc/librecmc.git] / target / linux / pistachio / patches-4.9 / 101-dmaengine-img-mdc-Handle-early-status-read.patch
1 From a2dd154377c9aa6ddda00d39b8c7c334e4fa16ff Mon Sep 17 00:00:00 2001
2 From: Damien Horsley <damien.horsley@imgtec.com>
3 Date: Tue, 22 Mar 2016 12:46:09 +0000
4 Subject: dmaengine: img-mdc: Handle early status read
5
6 It is possible that mdc_tx_status may be called before the first
7 node has been read from memory.
8
9 In this case, the residue value stored in the register is undefined.
10 Return the transfer size instead.
11
12 Signed-off-by: Damien Horsley <damien.horsley@imgtec.com>
13 ---
14  drivers/dma/img-mdc-dma.c | 40 ++++++++++++++++++++++++----------------
15  1 file changed, 24 insertions(+), 16 deletions(-)
16
17 diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c
18 index 624f1e1..0216e2c 100644
19 --- a/drivers/dma/img-mdc-dma.c
20 +++ b/drivers/dma/img-mdc-dma.c
21 @@ -623,25 +623,33 @@ static enum dma_status mdc_tx_status(struct dma_chan *chan,
22                         (MDC_CMDS_PROCESSED_CMDS_DONE_MASK + 1);
23  
24                 /*
25 -                * If the command loaded event hasn't been processed yet, then
26 -                * the difference above includes an extra command.
27 +                * If the first node has not yet been read from memory,
28 +                * the residue register value is undefined
29                  */
30 -               if (!mdesc->cmd_loaded)
31 -                       cmds--;
32 -               else
33 -                       cmds += mdesc->list_cmds_done;
34 -
35 -               bytes = mdesc->list_xfer_size;
36 -               ldesc = mdesc->list;
37 -               for (i = 0; i < cmds; i++) {
38 -                       bytes -= ldesc->xfer_size + 1;
39 -                       ldesc = ldesc->next_desc;
40 -               }
41 -               if (ldesc) {
42 -                       if (residue != MDC_TRANSFER_SIZE_MASK)
43 -                               bytes -= ldesc->xfer_size - residue;
44 +               if (!mdesc->cmd_loaded && !cmds) {
45 +                       bytes = mdesc->list_xfer_size;
46 +               } else {
47 +                       /*
48 +                        * If the command loaded event hasn't been processed yet, then
49 +                        * the difference above includes an extra command.
50 +                        */
51 +                       if (!mdesc->cmd_loaded)
52 +                               cmds--;
53                         else
54 +                               cmds += mdesc->list_cmds_done;
55 +
56 +                       bytes = mdesc->list_xfer_size;
57 +                       ldesc = mdesc->list;
58 +                       for (i = 0; i < cmds; i++) {
59                                 bytes -= ldesc->xfer_size + 1;
60 +                               ldesc = ldesc->next_desc;
61 +                       }
62 +                       if (ldesc) {
63 +                               if (residue != MDC_TRANSFER_SIZE_MASK)
64 +                                       bytes -= ldesc->xfer_size - residue;
65 +                               else
66 +                                       bytes -= ldesc->xfer_size + 1;
67 +                       }
68                 }
69         }
70         spin_unlock_irqrestore(&mchan->vc.lock, flags);
71 -- 
72 2.7.4
73