diff options
Diffstat (limited to 'arch/arm/plat-s3c24xx/dma.c')
-rw-r--r-- | arch/arm/plat-s3c24xx/dma.c | 77 |
1 files changed, 53 insertions, 24 deletions
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 929265aab7dd..4540a806f522 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c | |||
@@ -42,6 +42,8 @@ | |||
42 | static void __iomem *dma_base; | 42 | static void __iomem *dma_base; |
43 | static struct kmem_cache *dma_kmem; | 43 | static struct kmem_cache *dma_kmem; |
44 | 44 | ||
45 | static int dma_channels; | ||
46 | |||
45 | struct s3c24xx_dma_selection dma_sel; | 47 | struct s3c24xx_dma_selection dma_sel; |
46 | 48 | ||
47 | /* dma channel state information */ | 49 | /* dma channel state information */ |
@@ -1278,7 +1280,42 @@ static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long | |||
1278 | 1280 | ||
1279 | /* initialisation code */ | 1281 | /* initialisation code */ |
1280 | 1282 | ||
1281 | static int __init s3c2410_init_dma(void) | 1283 | int __init s3c24xx_dma_sysclass_init(void) |
1284 | { | ||
1285 | int ret = sysdev_class_register(&dma_sysclass); | ||
1286 | |||
1287 | if (ret != 0) | ||
1288 | printk(KERN_ERR "dma sysclass registration failed\n"); | ||
1289 | |||
1290 | return ret; | ||
1291 | } | ||
1292 | |||
1293 | core_initcall(s3c24xx_dma_sysclass_init); | ||
1294 | |||
1295 | int __init s3c24xx_dma_sysdev_register(void) | ||
1296 | { | ||
1297 | struct s3c2410_dma_chan *cp = s3c2410_chans; | ||
1298 | int channel, ret; | ||
1299 | |||
1300 | for (channel = 0; channel < dma_channels; cp++, channel++) { | ||
1301 | cp->dev.cls = &dma_sysclass; | ||
1302 | cp->dev.id = channel; | ||
1303 | ret = sysdev_register(&cp->dev); | ||
1304 | |||
1305 | if (ret) { | ||
1306 | printk(KERN_ERR "error registering dev for dma %d\n", | ||
1307 | channel); | ||
1308 | return ret; | ||
1309 | } | ||
1310 | } | ||
1311 | |||
1312 | return 0; | ||
1313 | } | ||
1314 | |||
1315 | late_initcall(s3c24xx_dma_sysdev_register); | ||
1316 | |||
1317 | int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq, | ||
1318 | unsigned int stride) | ||
1282 | { | 1319 | { |
1283 | struct s3c2410_dma_chan *cp; | 1320 | struct s3c2410_dma_chan *cp; |
1284 | int channel; | 1321 | int channel; |
@@ -1286,21 +1323,16 @@ static int __init s3c2410_init_dma(void) | |||
1286 | 1323 | ||
1287 | printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n"); | 1324 | printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n"); |
1288 | 1325 | ||
1289 | dma_base = ioremap(S3C24XX_PA_DMA, 0x200); | 1326 | dma_channels = channels; |
1327 | |||
1328 | dma_base = ioremap(S3C24XX_PA_DMA, stride * channels); | ||
1290 | if (dma_base == NULL) { | 1329 | if (dma_base == NULL) { |
1291 | printk(KERN_ERR "dma failed to remap register block\n"); | 1330 | printk(KERN_ERR "dma failed to remap register block\n"); |
1292 | return -ENOMEM; | 1331 | return -ENOMEM; |
1293 | } | 1332 | } |
1294 | 1333 | ||
1295 | printk("Registering sysclass\n"); | 1334 | dma_kmem = kmem_cache_create("dma_desc", |
1296 | 1335 | sizeof(struct s3c2410_dma_buf), 0, | |
1297 | ret = sysdev_class_register(&dma_sysclass); | ||
1298 | if (ret != 0) { | ||
1299 | printk(KERN_ERR "dma sysclass registration failed\n"); | ||
1300 | goto err; | ||
1301 | } | ||
1302 | |||
1303 | dma_kmem = kmem_cache_create("dma_desc", sizeof(struct s3c2410_dma_buf), 0, | ||
1304 | SLAB_HWCACHE_ALIGN, | 1336 | SLAB_HWCACHE_ALIGN, |
1305 | s3c2410_dma_cache_ctor, NULL); | 1337 | s3c2410_dma_cache_ctor, NULL); |
1306 | 1338 | ||
@@ -1310,15 +1342,15 @@ static int __init s3c2410_init_dma(void) | |||
1310 | goto err; | 1342 | goto err; |
1311 | } | 1343 | } |
1312 | 1344 | ||
1313 | for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) { | 1345 | for (channel = 0; channel < channels; channel++) { |
1314 | cp = &s3c2410_chans[channel]; | 1346 | cp = &s3c2410_chans[channel]; |
1315 | 1347 | ||
1316 | memset(cp, 0, sizeof(struct s3c2410_dma_chan)); | 1348 | memset(cp, 0, sizeof(struct s3c2410_dma_chan)); |
1317 | 1349 | ||
1318 | /* dma channel irqs are in order.. */ | 1350 | /* dma channel irqs are in order.. */ |
1319 | cp->number = channel; | 1351 | cp->number = channel; |
1320 | cp->irq = channel + IRQ_DMA0; | 1352 | cp->irq = channel + irq; |
1321 | cp->regs = dma_base + (channel*0x40); | 1353 | cp->regs = dma_base + (channel * stride); |
1322 | 1354 | ||
1323 | /* point current stats somewhere */ | 1355 | /* point current stats somewhere */ |
1324 | cp->stats = &cp->stats_store; | 1356 | cp->stats = &cp->stats_store; |
@@ -1328,12 +1360,6 @@ static int __init s3c2410_init_dma(void) | |||
1328 | 1360 | ||
1329 | cp->load_timeout = 1<<18; | 1361 | cp->load_timeout = 1<<18; |
1330 | 1362 | ||
1331 | /* register system device */ | ||
1332 | |||
1333 | cp->dev.cls = &dma_sysclass; | ||
1334 | cp->dev.id = channel; | ||
1335 | ret = sysdev_register(&cp->dev); | ||
1336 | |||
1337 | printk("DMA channel %d at %p, irq %d\n", | 1363 | printk("DMA channel %d at %p, irq %d\n", |
1338 | cp->number, cp->regs, cp->irq); | 1364 | cp->number, cp->regs, cp->irq); |
1339 | } | 1365 | } |
@@ -1347,7 +1373,10 @@ static int __init s3c2410_init_dma(void) | |||
1347 | return ret; | 1373 | return ret; |
1348 | } | 1374 | } |
1349 | 1375 | ||
1350 | core_initcall(s3c2410_init_dma); | 1376 | int s3c2410_dma_init(void) |
1377 | { | ||
1378 | return s3c24xx_dma_init(4, IRQ_DMA0, 0x40); | ||
1379 | } | ||
1351 | 1380 | ||
1352 | static inline int is_channel_valid(unsigned int channel) | 1381 | static inline int is_channel_valid(unsigned int channel) |
1353 | { | 1382 | { |
@@ -1384,7 +1413,7 @@ struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) | |||
1384 | if (dma_order) { | 1413 | if (dma_order) { |
1385 | ord = &dma_order->channels[channel]; | 1414 | ord = &dma_order->channels[channel]; |
1386 | 1415 | ||
1387 | for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) { | 1416 | for (ch = 0; ch < dma_channels; ch++) { |
1388 | if (!is_channel_valid(ord->list[ch])) | 1417 | if (!is_channel_valid(ord->list[ch])) |
1389 | continue; | 1418 | continue; |
1390 | 1419 | ||
@@ -1400,7 +1429,7 @@ struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) | |||
1400 | 1429 | ||
1401 | /* second, search the channel map for first free */ | 1430 | /* second, search the channel map for first free */ |
1402 | 1431 | ||
1403 | for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) { | 1432 | for (ch = 0; ch < dma_channels; ch++) { |
1404 | if (!is_channel_valid(ch_map->channels[ch])) | 1433 | if (!is_channel_valid(ch_map->channels[ch])) |
1405 | continue; | 1434 | continue; |
1406 | 1435 | ||
@@ -1410,7 +1439,7 @@ struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) | |||
1410 | } | 1439 | } |
1411 | } | 1440 | } |
1412 | 1441 | ||
1413 | if (ch >= S3C2410_DMA_CHANNELS) | 1442 | if (ch >= dma_channels) |
1414 | return NULL; | 1443 | return NULL; |
1415 | 1444 | ||
1416 | /* update our channel mapping */ | 1445 | /* update our channel mapping */ |