diff options
| author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2010-04-19 04:39:39 -0400 |
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2010-04-26 03:04:48 -0400 |
| commit | 83515bc7df812555e20cda48614674e2f346f9f5 (patch) | |
| tree | c0ca604767a430ae328c5e44a6e3e0dada89345f | |
| parent | e3a4317e1d9970c56ba19d29393e4289809a1aa5 (diff) | |
SH: fix error paths in DMA driver
If channel allocation is failing, mark the channel unused and give PM a chance
to power down the hardware.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
| -rw-r--r-- | drivers/dma/shdma.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 7cc31b3f40d8..6f25a20de99f 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
| @@ -290,6 +290,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | |||
| 290 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); | 290 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); |
| 291 | struct sh_desc *desc; | 291 | struct sh_desc *desc; |
| 292 | struct sh_dmae_slave *param = chan->private; | 292 | struct sh_dmae_slave *param = chan->private; |
| 293 | int ret; | ||
| 293 | 294 | ||
| 294 | pm_runtime_get_sync(sh_chan->dev); | 295 | pm_runtime_get_sync(sh_chan->dev); |
| 295 | 296 | ||
| @@ -301,11 +302,15 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | |||
| 301 | struct sh_dmae_slave_config *cfg; | 302 | struct sh_dmae_slave_config *cfg; |
| 302 | 303 | ||
| 303 | cfg = sh_dmae_find_slave(sh_chan, param->slave_id); | 304 | cfg = sh_dmae_find_slave(sh_chan, param->slave_id); |
| 304 | if (!cfg) | 305 | if (!cfg) { |
| 305 | return -EINVAL; | 306 | ret = -EINVAL; |
| 307 | goto efindslave; | ||
| 308 | } | ||
| 306 | 309 | ||
| 307 | 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)) { |
| 308 | return -EBUSY; | 311 | ret = -EBUSY; |
| 312 | goto etestused; | ||
| 313 | } | ||
| 309 | 314 | ||
| 310 | param->config = cfg; | 315 | param->config = cfg; |
| 311 | 316 | ||
| @@ -334,10 +339,20 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) | |||
| 334 | } | 339 | } |
| 335 | spin_unlock_bh(&sh_chan->desc_lock); | 340 | spin_unlock_bh(&sh_chan->desc_lock); |
| 336 | 341 | ||
| 337 | if (!sh_chan->descs_allocated) | 342 | if (!sh_chan->descs_allocated) { |
| 338 | pm_runtime_put(sh_chan->dev); | 343 | ret = -ENOMEM; |
| 344 | goto edescalloc; | ||
| 345 | } | ||
| 339 | 346 | ||
| 340 | 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; | ||
| 341 | } | 356 | } |
| 342 | 357 | ||
| 343 | /* | 358 | /* |
