apm821xx: dw_dmac: backport fixes and cleanups from 4.7
[openwrt/openwrt.git] / target / linux / apm821xx / patches-4.4 / 010-dmaengine-Add-transfer-termination-synchronization-s.patch
1 From 7bd903c5ca47fde5ad52370a47776491813c772e Mon Sep 17 00:00:00 2001
2 From: Peter Ujfalusi <peter.ujfalusi@ti.com>
3 Date: Mon, 14 Dec 2015 22:47:39 +0200
4 Subject: [PATCH 1/3] dmaengine: core: Move and merge the code paths using
5 private_candidate
6
7 Channel matching with private_candidate() is used in two paths, the error
8 checking is slightly different in them and they are duplicating code also.
9 Move the code under find_candidate() to provide consistent execution and
10 going to allow us to reuse this mode of channel lookup later.
11
12 Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
13 Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
14 Reviewed-by: Arnd Bergmann <arnd@arndb.de>
15 Signed-off-by: Vinod Koul <vinod.koul@intel.com>
16 ---
17 drivers/dma/dmaengine.c | 81 +++++++++++++++++++++++++------------------------
18 1 file changed, 42 insertions(+), 39 deletions(-)
19
20 diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
21 index f2cbff9..81a36fc 100644
22 --- a/drivers/dma/dmaengine.c
23 +++ b/drivers/dma/dmaengine.c
24 @@ -542,6 +542,42 @@ static struct dma_chan *private_candidate(const dma_cap_mask_t *mask,
25 return NULL;
26 }
27
28 +static struct dma_chan *find_candidate(struct dma_device *device,
29 + const dma_cap_mask_t *mask,
30 + dma_filter_fn fn, void *fn_param)
31 +{
32 + struct dma_chan *chan = private_candidate(mask, device, fn, fn_param);
33 + int err;
34 +
35 + if (chan) {
36 + /* Found a suitable channel, try to grab, prep, and return it.
37 + * We first set DMA_PRIVATE to disable balance_ref_count as this
38 + * channel will not be published in the general-purpose
39 + * allocator
40 + */
41 + dma_cap_set(DMA_PRIVATE, device->cap_mask);
42 + device->privatecnt++;
43 + err = dma_chan_get(chan);
44 +
45 + if (err) {
46 + if (err == -ENODEV) {
47 + pr_debug("%s: %s module removed\n", __func__,
48 + dma_chan_name(chan));
49 + list_del_rcu(&device->global_node);
50 + } else
51 + pr_debug("%s: failed to get %s: (%d)\n",
52 + __func__, dma_chan_name(chan), err);
53 +
54 + if (--device->privatecnt == 0)
55 + dma_cap_clear(DMA_PRIVATE, device->cap_mask);
56 +
57 + chan = ERR_PTR(err);
58 + }
59 + }
60 +
61 + return chan ? chan : ERR_PTR(-EPROBE_DEFER);
62 +}
63 +
64 /**
65 * dma_get_slave_channel - try to get specific channel exclusively
66 * @chan: target channel
67 @@ -580,7 +616,6 @@ struct dma_chan *dma_get_any_slave_channel(struct dma_device *device)
68 {
69 dma_cap_mask_t mask;
70 struct dma_chan *chan;
71 - int err;
72
73 dma_cap_zero(mask);
74 dma_cap_set(DMA_SLAVE, mask);
75 @@ -588,23 +623,11 @@ struct dma_chan *dma_get_any_slave_channel(struct dma_device *device)
76 /* lock against __dma_request_channel */
77 mutex_lock(&dma_list_mutex);
78
79 - chan = private_candidate(&mask, device, NULL, NULL);
80 - if (chan) {
81 - dma_cap_set(DMA_PRIVATE, device->cap_mask);
82 - device->privatecnt++;
83 - err = dma_chan_get(chan);
84 - if (err) {
85 - pr_debug("%s: failed to get %s: (%d)\n",
86 - __func__, dma_chan_name(chan), err);
87 - chan = NULL;
88 - if (--device->privatecnt == 0)
89 - dma_cap_clear(DMA_PRIVATE, device->cap_mask);
90 - }
91 - }
92 + chan = find_candidate(device, &mask, NULL, NULL);
93
94 mutex_unlock(&dma_list_mutex);
95
96 - return chan;
97 + return IS_ERR(chan) ? NULL : chan;
98 }
99 EXPORT_SYMBOL_GPL(dma_get_any_slave_channel);
100
101 @@ -621,35 +644,15 @@ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
102 {
103 struct dma_device *device, *_d;
104 struct dma_chan *chan = NULL;
105 - int err;
106
107 /* Find a channel */
108 mutex_lock(&dma_list_mutex);
109 list_for_each_entry_safe(device, _d, &dma_device_list, global_node) {
110 - chan = private_candidate(mask, device, fn, fn_param);
111 - if (chan) {
112 - /* Found a suitable channel, try to grab, prep, and
113 - * return it. We first set DMA_PRIVATE to disable
114 - * balance_ref_count as this channel will not be
115 - * published in the general-purpose allocator
116 - */
117 - dma_cap_set(DMA_PRIVATE, device->cap_mask);
118 - device->privatecnt++;
119 - err = dma_chan_get(chan);
120 + chan = find_candidate(device, mask, fn, fn_param);
121 + if (!IS_ERR(chan))
122 + break;
123
124 - if (err == -ENODEV) {
125 - pr_debug("%s: %s module removed\n",
126 - __func__, dma_chan_name(chan));
127 - list_del_rcu(&device->global_node);
128 - } else if (err)
129 - pr_debug("%s: failed to get %s: (%d)\n",
130 - __func__, dma_chan_name(chan), err);
131 - else
132 - break;
133 - if (--device->privatecnt == 0)
134 - dma_cap_clear(DMA_PRIVATE, device->cap_mask);
135 - chan = NULL;
136 - }
137 + chan = NULL;
138 }
139 mutex_unlock(&dma_list_mutex);
140
141 --
142 2.8.1
143