diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2014-11-17 08:41:58 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2014-12-22 01:58:55 -0500 |
commit | d2f4f99db3e9ec8b063cf2e45704e2bb95428317 (patch) | |
tree | 9977bcb2e3f8eacfd1f1417a2aa2ced074734661 /drivers/dma/dmaengine.c | |
parent | ceacbdbf65c4cf48a130db6152c6e03432c85ed1 (diff) |
dmaengine: Rework dma_chan_get
dma_chan_get uses a rather interesting error handling and code path.
Change it to something more usual in the kernel.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/dmaengine.c')
-rw-r--r-- | drivers/dma/dmaengine.c | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index e057935e3023..a5da0e147560 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -222,31 +222,33 @@ static void balance_ref_count(struct dma_chan *chan) | |||
222 | */ | 222 | */ |
223 | static int dma_chan_get(struct dma_chan *chan) | 223 | static int dma_chan_get(struct dma_chan *chan) |
224 | { | 224 | { |
225 | int err = -ENODEV; | ||
226 | struct module *owner = dma_chan_to_owner(chan); | 225 | struct module *owner = dma_chan_to_owner(chan); |
226 | int ret; | ||
227 | 227 | ||
228 | /* The channel is already in use, update client count */ | ||
228 | if (chan->client_count) { | 229 | if (chan->client_count) { |
229 | __module_get(owner); | 230 | __module_get(owner); |
230 | err = 0; | 231 | goto out; |
231 | } else if (try_module_get(owner)) | 232 | } |
232 | err = 0; | ||
233 | 233 | ||
234 | if (err == 0) | 234 | if (!try_module_get(owner)) |
235 | chan->client_count++; | 235 | return -ENODEV; |
236 | 236 | ||
237 | /* allocate upon first client reference */ | 237 | /* allocate upon first client reference */ |
238 | if (chan->client_count == 1 && err == 0) { | 238 | ret = chan->device->device_alloc_chan_resources(chan); |
239 | int desc_cnt = chan->device->device_alloc_chan_resources(chan); | 239 | if (ret < 0) |
240 | 240 | goto err_out; | |
241 | if (desc_cnt < 0) { | ||
242 | err = desc_cnt; | ||
243 | chan->client_count = 0; | ||
244 | module_put(owner); | ||
245 | } else if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask)) | ||
246 | balance_ref_count(chan); | ||
247 | } | ||
248 | 241 | ||
249 | return err; | 242 | if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask)) |
243 | balance_ref_count(chan); | ||
244 | |||
245 | out: | ||
246 | chan->client_count++; | ||
247 | return 0; | ||
248 | |||
249 | err_out: | ||
250 | module_put(owner); | ||
251 | return ret; | ||
250 | } | 252 | } |
251 | 253 | ||
252 | /** | 254 | /** |