diff options
Diffstat (limited to 'drivers/dma/shdma.c')
-rw-r--r-- | drivers/dma/shdma.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 5d17e09cb625..6f25a20de99f 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/slab.h> | ||
22 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
23 | #include <linux/dmaengine.h> | 24 | #include <linux/dmaengine.h> |
24 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
@@ -289,6 +290,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | |||
289 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); | 290 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); |
290 | struct sh_desc *desc; | 291 | struct sh_desc *desc; |
291 | struct sh_dmae_slave *param = chan->private; | 292 | struct sh_dmae_slave *param = chan->private; |
293 | int ret; | ||
292 | 294 | ||
293 | pm_runtime_get_sync(sh_chan->dev); | 295 | pm_runtime_get_sync(sh_chan->dev); |
294 | 296 | ||
@@ -300,11 +302,15 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | |||
300 | struct sh_dmae_slave_config *cfg; | 302 | struct sh_dmae_slave_config *cfg; |
301 | 303 | ||
302 | cfg = sh_dmae_find_slave(sh_chan, param->slave_id); | 304 | cfg = sh_dmae_find_slave(sh_chan, param->slave_id); |
303 | if (!cfg) | 305 | if (!cfg) { |
304 | return -EINVAL; | 306 | ret = -EINVAL; |
307 | goto efindslave; | ||
308 | } | ||
305 | 309 | ||
306 | if (test_and_set_bit(param->slave_id, sh_dmae_slave_used)) | 310 | if (test_and_set_bit(param->slave_id, sh_dmae_slave_used)) { |
307 | return -EBUSY; | 311 | ret = -EBUSY; |
312 | goto etestused; | ||
313 | } | ||
308 | 314 | ||
309 | param->config = cfg; | 315 | param->config = cfg; |
310 | 316 | ||
@@ -333,10 +339,20 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | |||
333 | } | 339 | } |
334 | spin_unlock_bh(&sh_chan->desc_lock); | 340 | spin_unlock_bh(&sh_chan->desc_lock); |
335 | 341 | ||
336 | if (!sh_chan->descs_allocated) | 342 | if (!sh_chan->descs_allocated) { |
337 | pm_runtime_put(sh_chan->dev); | 343 | ret = -ENOMEM; |
344 | goto edescalloc; | ||
345 | } | ||
338 | 346 | ||
339 | return sh_chan->descs_allocated; | 347 | return sh_chan->descs_allocated; |
348 | |||
349 | edescalloc: | ||
350 | if (param) | ||
351 | clear_bit(param->slave_id, sh_dmae_slave_used); | ||
352 | etestused: | ||
353 | efindslave: | ||
354 | pm_runtime_put(sh_chan->dev); | ||
355 | return ret; | ||
340 | } | 356 | } |
341 | 357 | ||
342 | /* | 358 | /* |