diff options
author | Vinod Koul <vinod.koul@intel.com> | 2014-01-07 17:06:24 +0100 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2014-01-07 17:06:24 +0100 |
commit | 0adcdeed6f87ac7230c9a0364ac785b8e70ad275 (patch) | |
tree | 77fd04c067b024887d801778227501762bdf2ddd | |
parent | Merge branch 'topic/defer_probe' into for-linus (diff) | |
parent | dma: add dma_get_any_slave_channel(), for use in of_xlate() (diff) | |
download | linux-0adcdeed6f87ac7230c9a0364ac785b8e70ad275.tar.xz linux-0adcdeed6f87ac7230c9a0364ac785b8e70ad275.zip |
Merge branch 'topic/of' into for-linus
Conflicts:
drivers/dma/mmp_pdma.c
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r-- | drivers/dma/dmaengine.c | 28 | ||||
-rw-r--r-- | drivers/dma/mmp_pdma.c | 17 | ||||
-rw-r--r-- | include/linux/dmaengine.h | 1 |
3 files changed, 33 insertions, 13 deletions
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index e17e9b22d85e..24095ff8a93b 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) } EXPORT_SYMBOL_GPL(dma_get_slave_channel); +struct dma_chan *dma_get_any_slave_channel(struct dma_device *device) +{ + dma_cap_mask_t mask; + struct dma_chan *chan; + int err; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + + /* lock against __dma_request_channel */ + mutex_lock(&dma_list_mutex); + + chan = private_candidate(&mask, device, NULL, NULL); + if (chan) { + err = dma_chan_get(chan); + if (err) { + pr_debug("%s: failed to get %s: (%d)\n", + __func__, dma_chan_name(chan), err); + chan = NULL; + } + } + + mutex_unlock(&dma_list_mutex); + + return chan; +} +EXPORT_SYMBOL_GPL(dma_get_any_slave_channel); + /** * __dma_request_channel - try to allocate an exclusive channel * @mask: capabilities that the channel must satisfy diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index 3f7712c4d3fa..c1b7c3ac7676 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -898,20 +898,11 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma) { struct mmp_pdma_device *d = ofdma->of_dma_data; - struct dma_chan *chan, *candidate; + struct dma_chan *chan; + struct mmp_pdma_chan *c; -retry: - candidate = NULL; - - /* walk the list of channels registered with the current instance and - * find one that is currently unused */ - list_for_each_entry(chan, &d->device.channels, device_node) - if (chan->client_count == 0) { - candidate = chan; - break; - } - - if (!candidate) + chan = dma_get_any_slave_channel(&d->device); + if (!chan) return NULL; /* dma_get_slave_channel will return NULL if we lost a race between diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index de550c61ba43..fa6b4285d8d2 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -1086,6 +1086,7 @@ int dma_async_device_register(struct dma_device *device); void dma_async_device_unregister(struct dma_device *device); void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_get_slave_channel(struct dma_chan *chan); +struct dma_chan *dma_get_any_slave_channel(struct dma_device *device); struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) #define dma_request_slave_channel_compat(mask, x, y, dev, name) \ |