diff options
| author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2015-01-27 08:58:53 -0500 |
|---|---|---|
| committer | Vinod Koul <vinod.koul@intel.com> | 2015-02-15 23:03:33 -0500 |
| commit | f7638c904bf87eac5bd823ef2debaef8251686b8 (patch) | |
| tree | 4e9d7587f6068af7623dd94ebe3d068985b1c31a /drivers/dma/sh | |
| parent | f39150720edcc9e6f5d61fd1ed6044eab1e5fa0d (diff) | |
dmaengine: rcar-dmac: Fix oops due to unintialized list in error ISR
The error interrupt handler stops and reinitializes all channels. This
causes a crash for channels that have never been used, as their
descriptor lists are uninitialized. Fix it by initializing the
descriptor lists at probe time.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/sh')
| -rw-r--r-- | drivers/dma/sh/rcar-dmac.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 5a6b85527107..2eb65e1bf938 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c | |||
| @@ -929,11 +929,6 @@ static int rcar_dmac_alloc_chan_resources(struct dma_chan *chan) | |||
| 929 | struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan); | 929 | struct rcar_dmac_chan *rchan = to_rcar_dmac_chan(chan); |
| 930 | int ret; | 930 | int ret; |
| 931 | 931 | ||
| 932 | INIT_LIST_HEAD(&rchan->desc.free); | ||
| 933 | INIT_LIST_HEAD(&rchan->desc.pending); | ||
| 934 | INIT_LIST_HEAD(&rchan->desc.active); | ||
| 935 | INIT_LIST_HEAD(&rchan->desc.done); | ||
| 936 | INIT_LIST_HEAD(&rchan->desc.wait); | ||
| 937 | INIT_LIST_HEAD(&rchan->desc.chunks_free); | 932 | INIT_LIST_HEAD(&rchan->desc.chunks_free); |
| 938 | INIT_LIST_HEAD(&rchan->desc.pages); | 933 | INIT_LIST_HEAD(&rchan->desc.pages); |
| 939 | 934 | ||
| @@ -970,11 +965,11 @@ static void rcar_dmac_free_chan_resources(struct dma_chan *chan) | |||
| 970 | rchan->mid_rid = -EINVAL; | 965 | rchan->mid_rid = -EINVAL; |
| 971 | } | 966 | } |
| 972 | 967 | ||
| 973 | list_splice(&rchan->desc.free, &list); | 968 | list_splice_init(&rchan->desc.free, &list); |
| 974 | list_splice(&rchan->desc.pending, &list); | 969 | list_splice_init(&rchan->desc.pending, &list); |
| 975 | list_splice(&rchan->desc.active, &list); | 970 | list_splice_init(&rchan->desc.active, &list); |
| 976 | list_splice(&rchan->desc.done, &list); | 971 | list_splice_init(&rchan->desc.done, &list); |
| 977 | list_splice(&rchan->desc.wait, &list); | 972 | list_splice_init(&rchan->desc.wait, &list); |
| 978 | 973 | ||
| 979 | list_for_each_entry(desc, &list, node) | 974 | list_for_each_entry(desc, &list, node) |
| 980 | rcar_dmac_realloc_hwdesc(rchan, desc, 0); | 975 | rcar_dmac_realloc_hwdesc(rchan, desc, 0); |
| @@ -1519,6 +1514,12 @@ static int rcar_dmac_chan_probe(struct rcar_dmac *dmac, | |||
| 1519 | 1514 | ||
| 1520 | spin_lock_init(&rchan->lock); | 1515 | spin_lock_init(&rchan->lock); |
| 1521 | 1516 | ||
| 1517 | INIT_LIST_HEAD(&rchan->desc.free); | ||
| 1518 | INIT_LIST_HEAD(&rchan->desc.pending); | ||
| 1519 | INIT_LIST_HEAD(&rchan->desc.active); | ||
| 1520 | INIT_LIST_HEAD(&rchan->desc.done); | ||
| 1521 | INIT_LIST_HEAD(&rchan->desc.wait); | ||
| 1522 | |||
| 1522 | /* Request the channel interrupt. */ | 1523 | /* Request the channel interrupt. */ |
| 1523 | sprintf(pdev_irqname, "ch%u", index); | 1524 | sprintf(pdev_irqname, "ch%u", index); |
| 1524 | irq = platform_get_irq_byname(pdev, pdev_irqname); | 1525 | irq = platform_get_irq_byname(pdev, pdev_irqname); |
