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.c48
1 files changed, 39 insertions, 9 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index b939e163f3b1..f993955a640c 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>
@@ -319,6 +320,7 @@ struct sdma_engine {
319 dma_addr_t context_phys; 320 dma_addr_t context_phys;
320 struct dma_device dma_device; 321 struct dma_device dma_device;
321 struct clk *clk; 322 struct clk *clk;
323 struct mutex channel_0_lock;
322 struct sdma_script_start_addrs *script_addrs; 324 struct sdma_script_start_addrs *script_addrs;
323}; 325};
324 326
@@ -416,11 +418,15 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
416 dma_addr_t buf_phys; 418 dma_addr_t buf_phys;
417 int ret; 419 int ret;
418 420
421 mutex_lock(&sdma->channel_0_lock);
422
419 buf_virt = dma_alloc_coherent(NULL, 423 buf_virt = dma_alloc_coherent(NULL,
420 size, 424 size,
421 &buf_phys, GFP_KERNEL); 425 &buf_phys, GFP_KERNEL);
422 if (!buf_virt) 426 if (!buf_virt) {
423 return -ENOMEM; 427 ret = -ENOMEM;
428 goto err_out;
429 }
424 430
425 bd0->mode.command = C0_SETPM; 431 bd0->mode.command = C0_SETPM;
426 bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD; 432 bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
@@ -434,6 +440,9 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
434 440
435 dma_free_coherent(NULL, size, buf_virt, buf_phys); 441 dma_free_coherent(NULL, size, buf_virt, buf_phys);
436 442
443err_out:
444 mutex_unlock(&sdma->channel_0_lock);
445
437 return ret; 446 return ret;
438} 447}
439 448
@@ -657,6 +666,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
657 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);
658 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);
659 668
669 mutex_lock(&sdma->channel_0_lock);
670
660 memset(context, 0, sizeof(*context)); 671 memset(context, 0, sizeof(*context));
661 context->channel_state.pc = load_address; 672 context->channel_state.pc = load_address;
662 673
@@ -677,6 +688,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
677 688
678 ret = sdma_run_channel(&sdma->channel[0]); 689 ret = sdma_run_channel(&sdma->channel[0]);
679 690
691 mutex_unlock(&sdma->channel_0_lock);
692
680 return ret; 693 return ret;
681} 694}
682 695
@@ -1132,18 +1145,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
1132 saddr_arr[i] = addr_arr[i]; 1145 saddr_arr[i] = addr_arr[i];
1133} 1146}
1134 1147
1135static int __init sdma_get_firmware(struct sdma_engine *sdma, 1148static void sdma_load_firmware(const struct firmware *fw, void *context)
1136 const char *fw_name)
1137{ 1149{
1138 const struct firmware *fw; 1150 struct sdma_engine *sdma = context;
1139 const struct sdma_firmware_header *header; 1151 const struct sdma_firmware_header *header;
1140 int ret;
1141 const struct sdma_script_start_addrs *addr; 1152 const struct sdma_script_start_addrs *addr;
1142 unsigned short *ram_code; 1153 unsigned short *ram_code;
1143 1154
1144 ret = request_firmware(&fw, fw_name, sdma->dev); 1155 if (!fw) {
1145 if (ret) 1156 dev_err(sdma->dev, "firmware not found\n");
1146 return ret; 1157 return;
1158 }
1147 1159
1148 if (fw->size < sizeof(*header)) 1160 if (fw->size < sizeof(*header))
1149 goto err_firmware; 1161 goto err_firmware;
@@ -1173,6 +1185,16 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma,
1173 1185
1174err_firmware: 1186err_firmware:
1175 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);
1176 1198
1177 return ret; 1199 return ret;
1178} 1200}
@@ -1270,11 +1292,14 @@ static int __init sdma_probe(struct platform_device *pdev)
1270 struct sdma_platform_data *pdata = pdev->dev.platform_data; 1292 struct sdma_platform_data *pdata = pdev->dev.platform_data;
1271 int i; 1293 int i;
1272 struct sdma_engine *sdma; 1294 struct sdma_engine *sdma;
1295 s32 *saddr_arr;
1273 1296
1274 sdma = kzalloc(sizeof(*sdma), GFP_KERNEL); 1297 sdma = kzalloc(sizeof(*sdma), GFP_KERNEL);
1275 if (!sdma) 1298 if (!sdma)
1276 return -ENOMEM; 1299 return -ENOMEM;
1277 1300
1301 mutex_init(&sdma->channel_0_lock);
1302
1278 sdma->dev = &pdev->dev; 1303 sdma->dev = &pdev->dev;
1279 1304
1280 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1305 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1311,6 +1336,11 @@ static int __init sdma_probe(struct platform_device *pdev)
1311 goto err_alloc; 1336 goto err_alloc;
1312 } 1337 }
1313 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
1314 if (of_id) 1344 if (of_id)
1315 pdev->id_entry = of_id->data; 1345 pdev->id_entry = of_id->data;
1316 sdma->devtype = pdev->id_entry->driver_data; 1346 sdma->devtype = pdev->id_entry->driver_data;