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 aab352a63a4a..323afef77802 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> |
@@ -288,6 +289,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | |||
288 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); | 289 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); |
289 | struct sh_desc *desc; | 290 | struct sh_desc *desc; |
290 | struct sh_dmae_slave *param = chan->private; | 291 | struct sh_dmae_slave *param = chan->private; |
292 | int ret; | ||
291 | 293 | ||
292 | pm_runtime_get_sync(sh_chan->dev); | 294 | pm_runtime_get_sync(sh_chan->dev); |
293 | 295 | ||
@@ -299,11 +301,15 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | |||
299 | const struct sh_dmae_slave_config *cfg; | 301 | const struct sh_dmae_slave_config *cfg; |
300 | 302 | ||
301 | cfg = sh_dmae_find_slave(sh_chan, param); | 303 | cfg = sh_dmae_find_slave(sh_chan, param); |
302 | if (!cfg) | 304 | if (!cfg) { |
303 | return -EINVAL; | 305 | ret = -EINVAL; |
306 | goto efindslave; | ||
307 | } | ||
304 | 308 | ||
305 | if (test_and_set_bit(param->slave_id, sh_dmae_slave_used)) | 309 | if (test_and_set_bit(param->slave_id, sh_dmae_slave_used)) { |
306 | return -EBUSY; | 310 | ret = -EBUSY; |
311 | goto etestused; | ||
312 | } | ||
307 | 313 | ||
308 | param->config = cfg; | 314 | param->config = cfg; |
309 | 315 | ||
@@ -332,10 +338,20 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | |||
332 | } | 338 | } |
333 | spin_unlock_bh(&sh_chan->desc_lock); | 339 | spin_unlock_bh(&sh_chan->desc_lock); |
334 | 340 | ||
335 | if (!sh_chan->descs_allocated) | 341 | if (!sh_chan->descs_allocated) { |
336 | pm_runtime_put(sh_chan->dev); | 342 | ret = -ENOMEM; |
343 | goto edescalloc; | ||
344 | } | ||
337 | 345 | ||
338 | return sh_chan->descs_allocated; | 346 | return sh_chan->descs_allocated; |
347 | |||
348 | edescalloc: | ||
349 | if (param) | ||
350 | clear_bit(param->slave_id, sh_dmae_slave_used); | ||
351 | etestused: | ||
352 | efindslave: | ||
353 | pm_runtime_put(sh_chan->dev); | ||
354 | return ret; | ||
339 | } | 355 | } |
340 | 356 | ||
341 | /* | 357 | /* |