aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-s3c24xx/dma.c
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2007-02-17 09:37:14 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-02-17 10:00:34 -0500
commit48adbcf33b6087727a2db0b517c994a7ecfbeb0c (patch)
tree55ad8f006bfedbf5b2ec5b72bc1ede7f2c3383da /arch/arm/plat-s3c24xx/dma.c
parent15e4db7b8054ac171de946b9511655446dd29b8f (diff)
[ARM] 4220/1: S3C24XX: DMA system initialised from sysdev
This patch gets the DMA system for the S3C24XX ready for the S3C2443, which requires 6 dma channels at a different stride, and different base IRQ. The DMA system is now initialised from the same drivers which apply the DMA mappings, as well as removing the DMA sysdev intialisation out of the main init code (which is now being called from a sysdev probe, so cannot add a new sysdev) Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/plat-s3c24xx/dma.c')
-rw-r--r--arch/arm/plat-s3c24xx/dma.c77
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 @@
42static void __iomem *dma_base; 42static void __iomem *dma_base;
43static struct kmem_cache *dma_kmem; 43static struct kmem_cache *dma_kmem;
44 44
45static int dma_channels;
46
45struct s3c24xx_dma_selection dma_sel; 47struct 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
1281static int __init s3c2410_init_dma(void) 1283int __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
1293core_initcall(s3c24xx_dma_sysclass_init);
1294
1295int __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
1315late_initcall(s3c24xx_dma_sysdev_register);
1316
1317int __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
1350core_initcall(s3c2410_init_dma); 1376int s3c2410_dma_init(void)
1377{
1378 return s3c24xx_dma_init(4, IRQ_DMA0, 0x40);
1379}
1351 1380
1352static inline int is_channel_valid(unsigned int channel) 1381static 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 */