summaryrefslogtreecommitdiff
path: root/target/linux/apm821xx/patches-4.4/010-dmaengine-Add-transfer-termination-synchronization-s.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/apm821xx/patches-4.4/010-dmaengine-Add-transfer-termination-synchronization-s.patch')
-rw-r--r--target/linux/apm821xx/patches-4.4/010-dmaengine-Add-transfer-termination-synchronization-s.patch143
1 files changed, 143 insertions, 0 deletions
diff --git a/target/linux/apm821xx/patches-4.4/010-dmaengine-Add-transfer-termination-synchronization-s.patch b/target/linux/apm821xx/patches-4.4/010-dmaengine-Add-transfer-termination-synchronization-s.patch
new file mode 100644
index 0000000..924f797
--- /dev/null
+++ b/target/linux/apm821xx/patches-4.4/010-dmaengine-Add-transfer-termination-synchronization-s.patch
@@ -0,0 +1,143 @@
+From 7bd903c5ca47fde5ad52370a47776491813c772e Mon Sep 17 00:00:00 2001
+From: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Date: Mon, 14 Dec 2015 22:47:39 +0200
+Subject: [PATCH 1/3] dmaengine: core: Move and merge the code paths using
+ private_candidate
+
+Channel matching with private_candidate() is used in two paths, the error
+checking is slightly different in them and they are duplicating code also.
+Move the code under find_candidate() to provide consistent execution and
+going to allow us to reuse this mode of channel lookup later.
+
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Reviewed-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Vinod Koul <vinod.koul@intel.com>
+---
+ drivers/dma/dmaengine.c | 81 +++++++++++++++++++++++++------------------------
+ 1 file changed, 42 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
+index f2cbff9..81a36fc 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -542,6 +542,42 @@ static struct dma_chan *private_candidate(const dma_cap_mask_t *mask,
+ return NULL;
+ }
+
++static struct dma_chan *find_candidate(struct dma_device *device,
++ const dma_cap_mask_t *mask,
++ dma_filter_fn fn, void *fn_param)
++{
++ struct dma_chan *chan = private_candidate(mask, device, fn, fn_param);
++ int err;
++
++ if (chan) {
++ /* Found a suitable channel, try to grab, prep, and return it.
++ * We first set DMA_PRIVATE to disable balance_ref_count as this
++ * channel will not be published in the general-purpose
++ * allocator
++ */
++ dma_cap_set(DMA_PRIVATE, device->cap_mask);
++ device->privatecnt++;
++ err = dma_chan_get(chan);
++
++ if (err) {
++ if (err == -ENODEV) {
++ pr_debug("%s: %s module removed\n", __func__,
++ dma_chan_name(chan));
++ list_del_rcu(&device->global_node);
++ } else
++ pr_debug("%s: failed to get %s: (%d)\n",
++ __func__, dma_chan_name(chan), err);
++
++ if (--device->privatecnt == 0)
++ dma_cap_clear(DMA_PRIVATE, device->cap_mask);
++
++ chan = ERR_PTR(err);
++ }
++ }
++
++ return chan ? chan : ERR_PTR(-EPROBE_DEFER);
++}
++
+ /**
+ * dma_get_slave_channel - try to get specific channel exclusively
+ * @chan: target channel
+@@ -580,7 +616,6 @@ 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);
+@@ -588,23 +623,11 @@ struct dma_chan *dma_get_any_slave_channel(struct dma_device *device)
+ /* lock against __dma_request_channel */
+ mutex_lock(&dma_list_mutex);
+
+- chan = private_candidate(&mask, device, NULL, NULL);
+- if (chan) {
+- dma_cap_set(DMA_PRIVATE, device->cap_mask);
+- device->privatecnt++;
+- err = dma_chan_get(chan);
+- if (err) {
+- pr_debug("%s: failed to get %s: (%d)\n",
+- __func__, dma_chan_name(chan), err);
+- chan = NULL;
+- if (--device->privatecnt == 0)
+- dma_cap_clear(DMA_PRIVATE, device->cap_mask);
+- }
+- }
++ chan = find_candidate(device, &mask, NULL, NULL);
+
+ mutex_unlock(&dma_list_mutex);
+
+- return chan;
++ return IS_ERR(chan) ? NULL : chan;
+ }
+ EXPORT_SYMBOL_GPL(dma_get_any_slave_channel);
+
+@@ -621,35 +644,15 @@ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
+ {
+ struct dma_device *device, *_d;
+ struct dma_chan *chan = NULL;
+- int err;
+
+ /* Find a channel */
+ mutex_lock(&dma_list_mutex);
+ list_for_each_entry_safe(device, _d, &dma_device_list, global_node) {
+- chan = private_candidate(mask, device, fn, fn_param);
+- if (chan) {
+- /* Found a suitable channel, try to grab, prep, and
+- * return it. We first set DMA_PRIVATE to disable
+- * balance_ref_count as this channel will not be
+- * published in the general-purpose allocator
+- */
+- dma_cap_set(DMA_PRIVATE, device->cap_mask);
+- device->privatecnt++;
+- err = dma_chan_get(chan);
++ chan = find_candidate(device, mask, fn, fn_param);
++ if (!IS_ERR(chan))
++ break;
+
+- if (err == -ENODEV) {
+- pr_debug("%s: %s module removed\n",
+- __func__, dma_chan_name(chan));
+- list_del_rcu(&device->global_node);
+- } else if (err)
+- pr_debug("%s: failed to get %s: (%d)\n",
+- __func__, dma_chan_name(chan), err);
+- else
+- break;
+- if (--device->privatecnt == 0)
+- dma_cap_clear(DMA_PRIVATE, device->cap_mask);
+- chan = NULL;
+- }
++ chan = NULL;
+ }
+ mutex_unlock(&dma_list_mutex);
+
+--
+2.8.1
+