aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/shdma.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-05-19 22:57:38 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-05-19 22:57:38 -0400
commitffee72d4681c8777918268a96aef42bdeb6c367b (patch)
tree4baf91483886d561c198ed0524ab54b783273e86 /drivers/dma/shdma.c
parentfb54d268329846aa13b2bc44a64d90e9b7131192 (diff)
parentf72caf7e496465182eeda842ac66a5e75404ddf1 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/dma/shdma.c')
-rw-r--r--drivers/dma/shdma.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index ed3ef22e68a4..c2b0172a7589 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -189,7 +189,7 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
189 struct sh_dmae_device *shdev = container_of(sh_chan->common.device, 189 struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
190 struct sh_dmae_device, common); 190 struct sh_dmae_device, common);
191 struct sh_dmae_pdata *pdata = shdev->pdata; 191 struct sh_dmae_pdata *pdata = shdev->pdata;
192 struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id]; 192 const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
193 u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16); 193 u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16);
194 int shift = chan_pdata->dmars_bit; 194 int shift = chan_pdata->dmars_bit;
195 195
@@ -265,7 +265,7 @@ static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan)
265 return NULL; 265 return NULL;
266} 266}
267 267
268static struct sh_dmae_slave_config *sh_dmae_find_slave( 268static const struct sh_dmae_slave_config *sh_dmae_find_slave(
269 struct sh_dmae_chan *sh_chan, struct sh_dmae_slave *param) 269 struct sh_dmae_chan *sh_chan, struct sh_dmae_slave *param)
270{ 270{
271 struct dma_device *dma_dev = sh_chan->common.device; 271 struct dma_device *dma_dev = sh_chan->common.device;
@@ -289,6 +289,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
289 struct sh_dmae_chan *sh_chan = to_sh_chan(chan); 289 struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
290 struct sh_desc *desc; 290 struct sh_desc *desc;
291 struct sh_dmae_slave *param = chan->private; 291 struct sh_dmae_slave *param = chan->private;
292 int ret;
292 293
293 pm_runtime_get_sync(sh_chan->dev); 294 pm_runtime_get_sync(sh_chan->dev);
294 295
@@ -297,14 +298,18 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
297 * never runs concurrently with itself or free_chan_resources. 298 * never runs concurrently with itself or free_chan_resources.
298 */ 299 */
299 if (param) { 300 if (param) {
300 struct sh_dmae_slave_config *cfg; 301 const struct sh_dmae_slave_config *cfg;
301 302
302 cfg = sh_dmae_find_slave(sh_chan, param); 303 cfg = sh_dmae_find_slave(sh_chan, param);
303 if (!cfg) 304 if (!cfg) {
304 return -EINVAL; 305 ret = -EINVAL;
306 goto efindslave;
307 }
305 308
306 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)) {
307 return -EBUSY; 310 ret = -EBUSY;
311 goto etestused;
312 }
308 313
309 param->config = cfg; 314 param->config = cfg;
310 315
@@ -333,10 +338,20 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
333 } 338 }
334 spin_unlock_bh(&sh_chan->desc_lock); 339 spin_unlock_bh(&sh_chan->desc_lock);
335 340
336 if (!sh_chan->descs_allocated) 341 if (!sh_chan->descs_allocated) {
337 pm_runtime_put(sh_chan->dev); 342 ret = -ENOMEM;
343 goto edescalloc;
344 }
338 345
339 return sh_chan->descs_allocated; 346 return sh_chan->descs_allocated;
347
348edescalloc:
349 if (param)
350 clear_bit(param->slave_id, sh_dmae_slave_used);
351etestused:
352efindslave:
353 pm_runtime_put(sh_chan->dev);
354 return ret;
340} 355}
341 356
342/* 357/*
@@ -558,12 +573,14 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
558{ 573{
559 struct sh_dmae_slave *param; 574 struct sh_dmae_slave *param;
560 struct sh_dmae_chan *sh_chan; 575 struct sh_dmae_chan *sh_chan;
576 dma_addr_t slave_addr;
561 577
562 if (!chan) 578 if (!chan)
563 return NULL; 579 return NULL;
564 580
565 sh_chan = to_sh_chan(chan); 581 sh_chan = to_sh_chan(chan);
566 param = chan->private; 582 param = chan->private;
583 slave_addr = param->config->addr;
567 584
568 /* Someone calling slave DMA on a public channel? */ 585 /* Someone calling slave DMA on a public channel? */
569 if (!param || !sg_len) { 586 if (!param || !sg_len) {
@@ -576,7 +593,7 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
576 * if (param != NULL), this is a successfully requested slave channel, 593 * if (param != NULL), this is a successfully requested slave channel,
577 * therefore param->config != NULL too. 594 * therefore param->config != NULL too.
578 */ 595 */
579 return sh_dmae_prep_sg(sh_chan, sgl, sg_len, &param->config->addr, 596 return sh_dmae_prep_sg(sh_chan, sgl, sg_len, &slave_addr,
580 direction, flags); 597 direction, flags);
581} 598}
582 599
@@ -857,7 +874,7 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
857 int irq, unsigned long flags) 874 int irq, unsigned long flags)
858{ 875{
859 int err; 876 int err;
860 struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id]; 877 const struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id];
861 struct platform_device *pdev = to_platform_device(shdev->common.dev); 878 struct platform_device *pdev = to_platform_device(shdev->common.dev);
862 struct sh_dmae_chan *new_sh_chan; 879 struct sh_dmae_chan *new_sh_chan;
863 880