diff options
author | Stephen Warren <swarren@nvidia.com> | 2013-11-26 14:40:51 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2013-12-10 07:18:33 -0500 |
commit | 8010dad55a0ab0e829f3733854e5235eef4e2734 (patch) | |
tree | 1a853cb6960763860227891b1324ab9467d6e8c9 /drivers/dma | |
parent | 6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae (diff) |
dma: add dma_get_any_slave_channel(), for use in of_xlate()
mmp_pdma.c implements a custom of_xlate() function that is 95% identical
to what Tegra will need. Create a function to implement the common part,
so everyone doesn't just cut/paste the implementation.
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Vinod Koul <vinod.koul@intel.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: dmaengine@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/dmaengine.c | 28 | ||||
-rw-r--r-- | drivers/dma/mmp_pdma.c | 30 |
2 files changed, 35 insertions, 23 deletions
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index ea806bdc12ef..4f08ee8c17b4 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -535,6 +535,34 @@ struct dma_chan *dma_get_slave_channel(struct dma_chan *chan) | |||
535 | } | 535 | } |
536 | EXPORT_SYMBOL_GPL(dma_get_slave_channel); | 536 | EXPORT_SYMBOL_GPL(dma_get_slave_channel); |
537 | 537 | ||
538 | struct dma_chan *dma_get_any_slave_channel(struct dma_device *device) | ||
539 | { | ||
540 | dma_cap_mask_t mask; | ||
541 | struct dma_chan *chan; | ||
542 | int err; | ||
543 | |||
544 | dma_cap_zero(mask); | ||
545 | dma_cap_set(DMA_SLAVE, mask); | ||
546 | |||
547 | /* lock against __dma_request_channel */ | ||
548 | mutex_lock(&dma_list_mutex); | ||
549 | |||
550 | chan = private_candidate(&mask, device, NULL, NULL); | ||
551 | if (chan) { | ||
552 | err = dma_chan_get(chan); | ||
553 | if (err) { | ||
554 | pr_debug("%s: failed to get %s: (%d)\n", | ||
555 | __func__, dma_chan_name(chan), err); | ||
556 | chan = NULL; | ||
557 | } | ||
558 | } | ||
559 | |||
560 | mutex_unlock(&dma_list_mutex); | ||
561 | |||
562 | return chan; | ||
563 | } | ||
564 | EXPORT_SYMBOL_GPL(dma_get_any_slave_channel); | ||
565 | |||
538 | /** | 566 | /** |
539 | * __dma_request_channel - try to allocate an exclusive channel | 567 | * __dma_request_channel - try to allocate an exclusive channel |
540 | * @mask: capabilities that the channel must satisfy | 568 | * @mask: capabilities that the channel must satisfy |
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index dcb1e05149a7..2998f1bffac1 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c | |||
@@ -893,33 +893,17 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec, | |||
893 | struct of_dma *ofdma) | 893 | struct of_dma *ofdma) |
894 | { | 894 | { |
895 | struct mmp_pdma_device *d = ofdma->of_dma_data; | 895 | struct mmp_pdma_device *d = ofdma->of_dma_data; |
896 | struct dma_chan *chan, *candidate; | 896 | struct dma_chan *chan; |
897 | struct mmp_pdma_chan *c; | ||
897 | 898 | ||
898 | retry: | 899 | chan = dma_get_any_slave_channel(&d->device); |
899 | candidate = NULL; | 900 | if (!chan) |
900 | |||
901 | /* walk the list of channels registered with the current instance and | ||
902 | * find one that is currently unused */ | ||
903 | list_for_each_entry(chan, &d->device.channels, device_node) | ||
904 | if (chan->client_count == 0) { | ||
905 | candidate = chan; | ||
906 | break; | ||
907 | } | ||
908 | |||
909 | if (!candidate) | ||
910 | return NULL; | 901 | return NULL; |
911 | 902 | ||
912 | /* dma_get_slave_channel will return NULL if we lost a race between | 903 | c = to_mmp_pdma_chan(chan); |
913 | * the lookup and the reservation */ | 904 | c->drcmr = dma_spec->args[0]; |
914 | chan = dma_get_slave_channel(candidate); | ||
915 | |||
916 | if (chan) { | ||
917 | struct mmp_pdma_chan *c = to_mmp_pdma_chan(chan); | ||
918 | c->drcmr = dma_spec->args[0]; | ||
919 | return chan; | ||
920 | } | ||
921 | 905 | ||
922 | goto retry; | 906 | return chan; |
923 | } | 907 | } |
924 | 908 | ||
925 | static int mmp_pdma_probe(struct platform_device *op) | 909 | static int mmp_pdma_probe(struct platform_device *op) |