diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-11 23:35:11 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-11 23:35:11 -0400 |
| commit | cfb63bafdb87bbcdc5d6dbbca623d3f69475f118 (patch) | |
| tree | 6bc2f07f7818b0a6aafc08058ace24322c7bf5cd /drivers | |
| parent | a3ab02b4c5d2ba0eff137a9442b80944ce2d9366 (diff) | |
| parent | 765024697807ad1e1cac332aa891253ca4a339da (diff) | |
Merge branch 'fixes' of git://git.infradead.org/users/vkoul/slave-dma
Pull slave-dmaengine fixes from Vinod Koul:
"The first one fixes issue in pl330 to check for DT compatible and
the second one fixes omap-dma to start without delay"
* 'fixes' of git://git.infradead.org/users/vkoul/slave-dma:
dmaengine: omap-dma: Start DMA without delay for cyclic channels
DMA: PL330: Add check if device tree compatible
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/dma/omap-dma.c | 20 | ||||
| -rw-r--r-- | drivers/dma/pl330.c | 38 |
2 files changed, 41 insertions, 17 deletions
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index c4b4fd2acc42..08b43bf37158 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c | |||
| @@ -276,12 +276,20 @@ static void omap_dma_issue_pending(struct dma_chan *chan) | |||
| 276 | 276 | ||
| 277 | spin_lock_irqsave(&c->vc.lock, flags); | 277 | spin_lock_irqsave(&c->vc.lock, flags); |
| 278 | if (vchan_issue_pending(&c->vc) && !c->desc) { | 278 | if (vchan_issue_pending(&c->vc) && !c->desc) { |
| 279 | struct omap_dmadev *d = to_omap_dma_dev(chan->device); | 279 | /* |
| 280 | spin_lock(&d->lock); | 280 | * c->cyclic is used only by audio and in this case the DMA need |
| 281 | if (list_empty(&c->node)) | 281 | * to be started without delay. |
| 282 | list_add_tail(&c->node, &d->pending); | 282 | */ |
| 283 | spin_unlock(&d->lock); | 283 | if (!c->cyclic) { |
| 284 | tasklet_schedule(&d->task); | 284 | struct omap_dmadev *d = to_omap_dma_dev(chan->device); |
| 285 | spin_lock(&d->lock); | ||
| 286 | if (list_empty(&c->node)) | ||
| 287 | list_add_tail(&c->node, &d->pending); | ||
| 288 | spin_unlock(&d->lock); | ||
| 289 | tasklet_schedule(&d->task); | ||
| 290 | } else { | ||
| 291 | omap_dma_start_desc(c); | ||
| 292 | } | ||
| 285 | } | 293 | } |
| 286 | spin_unlock_irqrestore(&c->vc.lock, flags); | 294 | spin_unlock_irqrestore(&c->vc.lock, flags); |
| 287 | } | 295 | } |
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 718153122759..5dbc5946c4c3 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c | |||
| @@ -2882,7 +2882,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2882 | { | 2882 | { |
| 2883 | struct dma_pl330_platdata *pdat; | 2883 | struct dma_pl330_platdata *pdat; |
| 2884 | struct dma_pl330_dmac *pdmac; | 2884 | struct dma_pl330_dmac *pdmac; |
| 2885 | struct dma_pl330_chan *pch; | 2885 | struct dma_pl330_chan *pch, *_p; |
| 2886 | struct pl330_info *pi; | 2886 | struct pl330_info *pi; |
| 2887 | struct dma_device *pd; | 2887 | struct dma_device *pd; |
| 2888 | struct resource *res; | 2888 | struct resource *res; |
| @@ -2984,7 +2984,16 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2984 | ret = dma_async_device_register(pd); | 2984 | ret = dma_async_device_register(pd); |
| 2985 | if (ret) { | 2985 | if (ret) { |
| 2986 | dev_err(&adev->dev, "unable to register DMAC\n"); | 2986 | dev_err(&adev->dev, "unable to register DMAC\n"); |
| 2987 | goto probe_err2; | 2987 | goto probe_err3; |
| 2988 | } | ||
| 2989 | |||
| 2990 | if (adev->dev.of_node) { | ||
| 2991 | ret = of_dma_controller_register(adev->dev.of_node, | ||
| 2992 | of_dma_pl330_xlate, pdmac); | ||
| 2993 | if (ret) { | ||
| 2994 | dev_err(&adev->dev, | ||
| 2995 | "unable to register DMA to the generic DT DMA helpers\n"); | ||
| 2996 | } | ||
| 2988 | } | 2997 | } |
| 2989 | 2998 | ||
| 2990 | dev_info(&adev->dev, | 2999 | dev_info(&adev->dev, |
| @@ -2995,16 +3004,21 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2995 | pi->pcfg.data_bus_width / 8, pi->pcfg.num_chan, | 3004 | pi->pcfg.data_bus_width / 8, pi->pcfg.num_chan, |
| 2996 | pi->pcfg.num_peri, pi->pcfg.num_events); | 3005 | pi->pcfg.num_peri, pi->pcfg.num_events); |
| 2997 | 3006 | ||
| 2998 | ret = of_dma_controller_register(adev->dev.of_node, | ||
| 2999 | of_dma_pl330_xlate, pdmac); | ||
| 3000 | if (ret) { | ||
| 3001 | dev_err(&adev->dev, | ||
| 3002 | "unable to register DMA to the generic DT DMA helpers\n"); | ||
| 3003 | goto probe_err2; | ||
| 3004 | } | ||
| 3005 | |||
| 3006 | return 0; | 3007 | return 0; |
| 3008 | probe_err3: | ||
| 3009 | amba_set_drvdata(adev, NULL); | ||
| 3007 | 3010 | ||
| 3011 | /* Idle the DMAC */ | ||
| 3012 | list_for_each_entry_safe(pch, _p, &pdmac->ddma.channels, | ||
| 3013 | chan.device_node) { | ||
| 3014 | |||
| 3015 | /* Remove the channel */ | ||
| 3016 | list_del(&pch->chan.device_node); | ||
| 3017 | |||
| 3018 | /* Flush the channel */ | ||
| 3019 | pl330_control(&pch->chan, DMA_TERMINATE_ALL, 0); | ||
| 3020 | pl330_free_chan_resources(&pch->chan); | ||
| 3021 | } | ||
| 3008 | probe_err2: | 3022 | probe_err2: |
| 3009 | pl330_del(pi); | 3023 | pl330_del(pi); |
| 3010 | probe_err1: | 3024 | probe_err1: |
| @@ -3023,8 +3037,10 @@ static int pl330_remove(struct amba_device *adev) | |||
| 3023 | if (!pdmac) | 3037 | if (!pdmac) |
| 3024 | return 0; | 3038 | return 0; |
| 3025 | 3039 | ||
| 3026 | of_dma_controller_free(adev->dev.of_node); | 3040 | if (adev->dev.of_node) |
| 3041 | of_dma_controller_free(adev->dev.of_node); | ||
| 3027 | 3042 | ||
| 3043 | dma_async_device_unregister(&pdmac->ddma); | ||
| 3028 | amba_set_drvdata(adev, NULL); | 3044 | amba_set_drvdata(adev, NULL); |
| 3029 | 3045 | ||
| 3030 | /* Idle the DMAC */ | 3046 | /* Idle the DMAC */ |
