aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/imx-sdma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/imx-sdma.c')
-rw-r--r--drivers/dma/imx-sdma.c49
1 files changed, 40 insertions, 9 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 7bd7e98548c..f993955a640 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/module.h>
21#include <linux/types.h> 22#include <linux/types.h>
22#include <linux/mm.h> 23#include <linux/mm.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
@@ -34,6 +35,7 @@
34#include <linux/dmaengine.h> 35#include <linux/dmaengine.h>
35#include <linux/of.h> 36#include <linux/of.h>
36#include <linux/of_device.h> 37#include <linux/of_device.h>
38#include <linux/module.h>
37 39
38#include <asm/irq.h> 40#include <asm/irq.h>
39#include <mach/sdma.h> 41#include <mach/sdma.h>
@@ -318,6 +320,7 @@ struct sdma_engine {
318 dma_addr_t context_phys; 320 dma_addr_t context_phys;
319 struct dma_device dma_device; 321 struct dma_device dma_device;
320 struct clk *clk; 322 struct clk *clk;
323 struct mutex channel_0_lock;
321 struct sdma_script_start_addrs *script_addrs; 324 struct sdma_script_start_addrs *script_addrs;
322}; 325};
323 326
@@ -415,11 +418,15 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
415 dma_addr_t buf_phys; 418 dma_addr_t buf_phys;
416 int ret; 419 int ret;
417 420
421 mutex_lock(&sdma->channel_0_lock);
422
418 buf_virt = dma_alloc_coherent(NULL, 423 buf_virt = dma_alloc_coherent(NULL,
419 size, 424 size,
420 &buf_phys, GFP_KERNEL); 425 &buf_phys, GFP_KERNEL);
421 if (!buf_virt) 426 if (!buf_virt) {
422 return -ENOMEM; 427 ret = -ENOMEM;
428 goto err_out;
429 }
423 430
424 bd0->mode.command = C0_SETPM; 431 bd0->mode.command = C0_SETPM;
425 bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD; 432 bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
@@ -433,6 +440,9 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
433 440
434 dma_free_coherent(NULL, size, buf_virt, buf_phys); 441 dma_free_coherent(NULL, size, buf_virt, buf_phys);
435 442
443err_out:
444 mutex_unlock(&sdma->channel_0_lock);
445
436 return ret; 446 return ret;
437} 447}
438 448
@@ -656,6 +666,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
656 dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", sdmac->event_mask0); 666 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); 667 dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", sdmac->event_mask1);
658 668
669 mutex_lock(&sdma->channel_0_lock);
670
659 memset(context, 0, sizeof(*context)); 671 memset(context, 0, sizeof(*context));
660 context->channel_state.pc = load_address; 672 context->channel_state.pc = load_address;
661 673
@@ -676,6 +688,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
676 688
677 ret = sdma_run_channel(&sdma->channel[0]); 689 ret = sdma_run_channel(&sdma->channel[0]);
678 690
691 mutex_unlock(&sdma->channel_0_lock);
692
679 return ret; 693 return ret;
680} 694}
681 695
@@ -1131,18 +1145,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
1131 saddr_arr[i] = addr_arr[i]; 1145 saddr_arr[i] = addr_arr[i];
1132} 1146}
1133 1147
1134static int __init sdma_get_firmware(struct sdma_engine *sdma, 1148static void sdma_load_firmware(const struct firmware *fw, void *context)
1135 const char *fw_name)
1136{ 1149{
1137 const struct firmware *fw; 1150 struct sdma_engine *sdma = context;
1138 const struct sdma_firmware_header *header; 1151 const struct sdma_firmware_header *header;
1139 int ret;
1140 const struct sdma_script_start_addrs *addr; 1152 const struct sdma_script_start_addrs *addr;
1141 unsigned short *ram_code; 1153 unsigned short *ram_code;
1142 1154
1143 ret = request_firmware(&fw, fw_name, sdma->dev); 1155 if (!fw) {
1144 if (ret) 1156 dev_err(sdma->dev, "firmware not found\n");
1145 return ret; 1157 return;
1158 }
1146 1159
1147 if (fw->size < sizeof(*header)) 1160 if (fw->size < sizeof(*header))
1148 goto err_firmware; 1161 goto err_firmware;
@@ -1172,6 +1185,16 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma,
1172 1185
1173err_firmware: 1186err_firmware:
1174 release_firmware(fw); 1187 release_firmware(fw);
1188}
1189
1190static int __init sdma_get_firmware(struct sdma_engine *sdma,
1191 const char *fw_name)
1192{
1193 int ret;
1194
1195 ret = request_firmware_nowait(THIS_MODULE,
1196 FW_ACTION_HOTPLUG, fw_name, sdma->dev,
1197 GFP_KERNEL, sdma, sdma_load_firmware);
1175 1198
1176 return ret; 1199 return ret;
1177} 1200}
@@ -1269,11 +1292,14 @@ static int __init sdma_probe(struct platform_device *pdev)
1269 struct sdma_platform_data *pdata = pdev->dev.platform_data; 1292 struct sdma_platform_data *pdata = pdev->dev.platform_data;
1270 int i; 1293 int i;
1271 struct sdma_engine *sdma; 1294 struct sdma_engine *sdma;
1295 s32 *saddr_arr;
1272 1296
1273 sdma = kzalloc(sizeof(*sdma), GFP_KERNEL); 1297 sdma = kzalloc(sizeof(*sdma), GFP_KERNEL);
1274 if (!sdma) 1298 if (!sdma)
1275 return -ENOMEM; 1299 return -ENOMEM;
1276 1300
1301 mutex_init(&sdma->channel_0_lock);
1302
1277 sdma->dev = &pdev->dev; 1303 sdma->dev = &pdev->dev;
1278 1304
1279 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1305 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1310,6 +1336,11 @@ static int __init sdma_probe(struct platform_device *pdev)
1310 goto err_alloc; 1336 goto err_alloc;
1311 } 1337 }
1312 1338
1339 /* initially no scripts available */
1340 saddr_arr = (s32 *)sdma->script_addrs;
1341 for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++)
1342 saddr_arr[i] = -EINVAL;
1343
1313 if (of_id) 1344 if (of_id)
1314 pdev->id_entry = of_id->data; 1345 pdev->id_entry = of_id->data;
1315 sdma->devtype = pdev->id_entry->driver_data; 1346 sdma->devtype = pdev->id_entry->driver_data;