aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/dmaengine.c14
-rw-r--r--include/linux/dmaengine.h2
2 files changed, 12 insertions, 4 deletions
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 99c22b42bada..10de69eb1a3e 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -183,9 +183,10 @@ static void dma_client_chan_alloc(struct dma_client *client)
183 /* we are done once this client rejects 183 /* we are done once this client rejects
184 * an available resource 184 * an available resource
185 */ 185 */
186 if (ack == DMA_ACK) 186 if (ack == DMA_ACK) {
187 dma_chan_get(chan); 187 dma_chan_get(chan);
188 else if (ack == DMA_NAK) 188 chan->client_count++;
189 } else if (ack == DMA_NAK)
189 return; 190 return;
190 } 191 }
191 } 192 }
@@ -272,8 +273,10 @@ static void dma_clients_notify_removed(struct dma_chan *chan)
272 /* client was holding resources for this channel so 273 /* client was holding resources for this channel so
273 * free it 274 * free it
274 */ 275 */
275 if (ack == DMA_ACK) 276 if (ack == DMA_ACK) {
276 dma_chan_put(chan); 277 dma_chan_put(chan);
278 chan->client_count--;
279 }
277 } 280 }
278 281
279 mutex_unlock(&dma_list_mutex); 282 mutex_unlock(&dma_list_mutex);
@@ -313,8 +316,10 @@ void dma_async_client_unregister(struct dma_client *client)
313 ack = client->event_callback(client, chan, 316 ack = client->event_callback(client, chan,
314 DMA_RESOURCE_REMOVED); 317 DMA_RESOURCE_REMOVED);
315 318
316 if (ack == DMA_ACK) 319 if (ack == DMA_ACK) {
317 dma_chan_put(chan); 320 dma_chan_put(chan);
321 chan->client_count--;
322 }
318 } 323 }
319 324
320 list_del(&client->global_node); 325 list_del(&client->global_node);
@@ -394,6 +399,7 @@ int dma_async_device_register(struct dma_device *device)
394 kref_get(&device->refcount); 399 kref_get(&device->refcount);
395 kref_get(&device->refcount); 400 kref_get(&device->refcount);
396 kref_init(&chan->refcount); 401 kref_init(&chan->refcount);
402 chan->client_count = 0;
397 chan->slow_ref = 0; 403 chan->slow_ref = 0;
398 INIT_RCU_HEAD(&chan->rcu); 404 INIT_RCU_HEAD(&chan->rcu);
399 } 405 }
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index d08a5c5eb928..6432b8343220 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -139,6 +139,7 @@ struct dma_chan_percpu {
139 * @rcu: the DMA channel's RCU head 139 * @rcu: the DMA channel's RCU head
140 * @device_node: used to add this to the device chan list 140 * @device_node: used to add this to the device chan list
141 * @local: per-cpu pointer to a struct dma_chan_percpu 141 * @local: per-cpu pointer to a struct dma_chan_percpu
142 * @client-count: how many clients are using this channel
142 */ 143 */
143struct dma_chan { 144struct dma_chan {
144 struct dma_device *device; 145 struct dma_device *device;
@@ -154,6 +155,7 @@ struct dma_chan {
154 155
155 struct list_head device_node; 156 struct list_head device_node;
156 struct dma_chan_percpu *local; 157 struct dma_chan_percpu *local;
158 int client_count;
157}; 159};
158 160
159#define to_dma_chan(p) container_of(p, struct dma_chan, dev) 161#define to_dma_chan(p) container_of(p, struct dma_chan, dev)