@@ -674,6 +674,51 @@ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
}
EXPORT_SYMBOL_GPL(__dma_request_channel);
+static int get_candidate_count(const dma_cap_mask_t *mask,
+ struct dma_device *dev,
+ dma_filter_fn fn, void *fn_param)
+{
+ struct dma_chan *chan;
+ int count = 0;
+
+ if (mask && !__dma_device_satisfies_mask(dev, mask)) {
+ dev_dbg(dev->dev, "%s: wrong capabilities\n", __func__);
+ return 0;
+ }
+
+ list_for_each_entry(chan, &dev->channels, device_node) {
+ if (dma_has_cap(DMA_PRIVATE, dev->cap_mask)) {
+ dev_dbg(dev->dev, "%s: %s is marked for private\n",
+ __func__, dma_chan_name(chan));
+ continue;
+ }
+ if (fn && !fn(chan, fn_param)) {
+ dev_dbg(dev->dev, "%s: %s filter said false\n",
+ __func__, dma_chan_name(chan));
+ continue;
+ }
+ count++;
+ }
+
+ return count;
+}
+
+int dma_get_channel_count(const dma_cap_mask_t *mask,
+ dma_filter_fn fn, void *fn_param)
+{
+ struct dma_device *device;
+ int total = 0;
+
+ /* Find a channel */
+ mutex_lock(&dma_list_mutex);
+ list_for_each_entry(device, &dma_device_list, global_node)
+ total += get_candidate_count(mask, device, fn, fn_param);
+ mutex_unlock(&dma_list_mutex);
+
+ return total;
+}
+EXPORT_SYMBOL_GPL(dma_get_channel_count);
+
static const struct dma_slave_map *dma_filter_match(struct dma_device *device,
const char *name,
struct device *dev)
@@ -1331,6 +1331,8 @@ enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
void dma_issue_pending_all(void);
struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
dma_filter_fn fn, void *fn_param);
+int dma_get_channel_count(const dma_cap_mask_t *mask,
+ dma_filter_fn fn, void *fn_param);
struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name);
struct dma_chan *dma_request_chan(struct device *dev, const char *name);
@@ -1364,6 +1366,11 @@ static inline struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
{
return NULL;
}
+static int dma_get_channel_count(const dma_cap_mask_t *mask,
+ dma_filter_fn fn, void *fn_param)
+{
+ return 0;
+}
static inline struct dma_chan *dma_request_slave_channel(struct device *dev,
const char *name)
{
Adding a dmaengine support function to provide the number of available channels that can be shared with support of a filter function. Signed-off-by: Dave Jiang <dave.jiang@intel.com> --- drivers/dma/dmaengine.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/dmaengine.h | 7 +++++++ 2 files changed, 52 insertions(+)