|
@@ -222,31 +222,33 @@ static void balance_ref_count(struct dma_chan *chan)
|
|
*/
|
|
*/
|
|
static int dma_chan_get(struct dma_chan *chan)
|
|
static int dma_chan_get(struct dma_chan *chan)
|
|
{
|
|
{
|
|
- int err = -ENODEV;
|
|
|
|
struct module *owner = dma_chan_to_owner(chan);
|
|
struct module *owner = dma_chan_to_owner(chan);
|
|
|
|
+ int ret;
|
|
|
|
|
|
|
|
+ /* The channel is already in use, update client count */
|
|
if (chan->client_count) {
|
|
if (chan->client_count) {
|
|
__module_get(owner);
|
|
__module_get(owner);
|
|
- err = 0;
|
|
|
|
- } else if (try_module_get(owner))
|
|
|
|
- err = 0;
|
|
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
|
|
- if (err == 0)
|
|
|
|
- chan->client_count++;
|
|
|
|
|
|
+ if (!try_module_get(owner))
|
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
/* allocate upon first client reference */
|
|
/* allocate upon first client reference */
|
|
- if (chan->client_count == 1 && err == 0) {
|
|
|
|
- int desc_cnt = chan->device->device_alloc_chan_resources(chan);
|
|
|
|
-
|
|
|
|
- if (desc_cnt < 0) {
|
|
|
|
- err = desc_cnt;
|
|
|
|
- chan->client_count = 0;
|
|
|
|
- module_put(owner);
|
|
|
|
- } else if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
|
|
|
|
- balance_ref_count(chan);
|
|
|
|
- }
|
|
|
|
|
|
+ ret = chan->device->device_alloc_chan_resources(chan);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ goto err_out;
|
|
|
|
|
|
- return err;
|
|
|
|
|
|
+ if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
|
|
|
|
+ balance_ref_count(chan);
|
|
|
|
+
|
|
|
|
+out:
|
|
|
|
+ chan->client_count++;
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+err_out:
|
|
|
|
+ module_put(owner);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|