/** * dma_chan_get - try to grab a dma channel's parent driver module * @chan - channel to grab * * Must be called under dma_list_mutex */ static int dma_chan_get(struct dma_chan *chan) { int err = -ENODEV; struct module *owner = dma_chan_to_owner(chan); if (chan->client_count) { __module_get(owner); err = 0; } else if (try_module_get(owner)) err = 0; if (err == 0) chan->client_count++; /* 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); } return err; }
/** * dma_chan_get - try to grab a dma channel's parent driver module * @chan - channel to grab * * Must be called under dma_list_mutex */ static int dma_chan_get(struct dma_chan *chan) { struct module *owner = dma_chan_to_owner(chan); int ret; /* The channel is already in use, update client count */ if (chan->client_count) { __module_get(owner); goto out; } if (!try_module_get(owner)) return -ENODEV; /* allocate upon first client reference */ if (chan->device->device_alloc_chan_resources) { ret = chan->device->device_alloc_chan_resources(chan); if (ret < 0) goto err_out; } 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; }