diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2011-08-25 05:03:35 -0400 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2011-08-29 10:38:26 -0400 |
commit | 73eab978ad6934499b83ecc920d470fe99c5e54d (patch) | |
tree | 1f622269c883e767832a365557c2c504a3fd2fc3 /drivers/dma/imx-sdma.c | |
parent | 981ed70d8e4faf3689dbf3c48868a31d5b004d7a (diff) |
dmaengine i.MX SDMA: lock channel 0
channel0 of the sdma engine is the configuration channel. It
is a shared resource and thus must be protected by a mutex.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/imx-sdma.c')
-rw-r--r-- | drivers/dma/imx-sdma.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 7bd7e98548cd..f50c87c303dd 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c | |||
@@ -318,6 +318,7 @@ struct sdma_engine { | |||
318 | dma_addr_t context_phys; | 318 | dma_addr_t context_phys; |
319 | struct dma_device dma_device; | 319 | struct dma_device dma_device; |
320 | struct clk *clk; | 320 | struct clk *clk; |
321 | struct mutex channel_0_lock; | ||
321 | struct sdma_script_start_addrs *script_addrs; | 322 | struct sdma_script_start_addrs *script_addrs; |
322 | }; | 323 | }; |
323 | 324 | ||
@@ -415,11 +416,15 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, | |||
415 | dma_addr_t buf_phys; | 416 | dma_addr_t buf_phys; |
416 | int ret; | 417 | int ret; |
417 | 418 | ||
419 | mutex_lock(&sdma->channel_0_lock); | ||
420 | |||
418 | buf_virt = dma_alloc_coherent(NULL, | 421 | buf_virt = dma_alloc_coherent(NULL, |
419 | size, | 422 | size, |
420 | &buf_phys, GFP_KERNEL); | 423 | &buf_phys, GFP_KERNEL); |
421 | if (!buf_virt) | 424 | if (!buf_virt) { |
422 | return -ENOMEM; | 425 | ret = -ENOMEM; |
426 | goto err_out; | ||
427 | } | ||
423 | 428 | ||
424 | bd0->mode.command = C0_SETPM; | 429 | bd0->mode.command = C0_SETPM; |
425 | bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD; | 430 | bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD; |
@@ -433,6 +438,9 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, | |||
433 | 438 | ||
434 | dma_free_coherent(NULL, size, buf_virt, buf_phys); | 439 | dma_free_coherent(NULL, size, buf_virt, buf_phys); |
435 | 440 | ||
441 | err_out: | ||
442 | mutex_unlock(&sdma->channel_0_lock); | ||
443 | |||
436 | return ret; | 444 | return ret; |
437 | } | 445 | } |
438 | 446 | ||
@@ -656,6 +664,8 @@ static int sdma_load_context(struct sdma_channel *sdmac) | |||
656 | dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", sdmac->event_mask0); | 664 | dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", sdmac->event_mask0); |
657 | dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", sdmac->event_mask1); | 665 | dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", sdmac->event_mask1); |
658 | 666 | ||
667 | mutex_lock(&sdma->channel_0_lock); | ||
668 | |||
659 | memset(context, 0, sizeof(*context)); | 669 | memset(context, 0, sizeof(*context)); |
660 | context->channel_state.pc = load_address; | 670 | context->channel_state.pc = load_address; |
661 | 671 | ||
@@ -676,6 +686,8 @@ static int sdma_load_context(struct sdma_channel *sdmac) | |||
676 | 686 | ||
677 | ret = sdma_run_channel(&sdma->channel[0]); | 687 | ret = sdma_run_channel(&sdma->channel[0]); |
678 | 688 | ||
689 | mutex_unlock(&sdma->channel_0_lock); | ||
690 | |||
679 | return ret; | 691 | return ret; |
680 | } | 692 | } |
681 | 693 | ||
@@ -1274,6 +1286,8 @@ static int __init sdma_probe(struct platform_device *pdev) | |||
1274 | if (!sdma) | 1286 | if (!sdma) |
1275 | return -ENOMEM; | 1287 | return -ENOMEM; |
1276 | 1288 | ||
1289 | mutex_init(&sdma->channel_0_lock); | ||
1290 | |||
1277 | sdma->dev = &pdev->dev; | 1291 | sdma->dev = &pdev->dev; |
1278 | 1292 | ||
1279 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1293 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |