diff options
-rw-r--r-- | drivers/dma/dmaengine.c | 14 | ||||
-rw-r--r-- | include/linux/dmaengine.h | 2 |
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 | */ |
143 | struct dma_chan { | 144 | struct 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) |