diff -urpN -X linux-2.6.20-rmk-16feb2007-patch1/Documentation/dontdiff linux-2.6.20-rmk-16feb2007-patch1/include/asm-arm/plat-s3c24xx/dma.h linux-2.6.20-rmk-16feb2007-s3c2443-2/include/asm-arm/plat-s3c24xx/dma.h
--- linux-2.6.20-rmk-16feb2007-patch1/include/asm-arm/plat-s3c24xx/dma.h	2007-02-16 17:18:36.000000000 +0000
+++ linux-2.6.20-rmk-16feb2007-s3c2443-2/include/asm-arm/plat-s3c24xx/dma.h	2007-02-17 13:56:14.000000000 +0000
@@ -68,3 +68,10 @@ struct s3c24xx_dma_order {
 };
 
 extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
+
+/* DMA init code, called from the cpu support code */
+
+extern int s3c2410_dma_init(void);
+
+extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
+			    unsigned int stride);
diff -urpN -X linux-2.6.20-rmk-16feb2007-patch1/Documentation/dontdiff linux-2.6.20-rmk-16feb2007-patch1/arch/arm/plat-s3c24xx/dma.c linux-2.6.20-rmk-16feb2007-s3c2443-2/arch/arm/plat-s3c24xx/dma.c
--- linux-2.6.20-rmk-16feb2007-patch1/arch/arm/plat-s3c24xx/dma.c	2007-02-17 14:33:06.000000000 +0000
+++ linux-2.6.20-rmk-16feb2007-s3c2443-2/arch/arm/plat-s3c24xx/dma.c	2007-02-17 14:33:55.000000000 +0000
@@ -42,6 +42,8 @@
 static void __iomem *dma_base;
 static struct kmem_cache *dma_kmem;
 
+static int dma_channels;
+
 struct s3c24xx_dma_selection dma_sel;
 
 /* dma channel state information */
@@ -1278,7 +1280,42 @@ static void s3c2410_dma_cache_ctor(void 
 
 /* initialisation code */
 
-static int __init s3c2410_init_dma(void)
+int __init s3c24xx_dma_sysclass_init(void)
+{
+	int ret = sysdev_class_register(&dma_sysclass);
+
+	if (ret != 0) 
+		printk(KERN_ERR "dma sysclass registration failed\n");
+
+	return ret;
+}
+
+core_initcall(s3c24xx_dma_sysclass_init);
+
+int __init s3c24xx_dma_sysdev_register(void)
+{
+	struct s3c2410_dma_chan *cp = s3c2410_chans;
+	int channel, ret;
+
+	for (channel = 0; channel < dma_channels; cp++, channel++) {
+		cp->dev.cls = &dma_sysclass;
+		cp->dev.id  = channel;
+		ret = sysdev_register(&cp->dev);
+
+		if (ret) {
+			printk(KERN_ERR "error registering dev for dma %d\n",
+			       channel);
+ 			return ret;
+		}
+	}
+
+	return 0;
+}
+
+late_initcall(s3c24xx_dma_sysdev_register);
+
+int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
+			    unsigned int stride)
 {
 	struct s3c2410_dma_chan *cp;
 	int channel;
@@ -1286,21 +1323,16 @@ static int __init s3c2410_init_dma(void)
 
 	printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
 
-	dma_base = ioremap(S3C24XX_PA_DMA, 0x200);
+	dma_channels = channels;
+
+	dma_base = ioremap(S3C24XX_PA_DMA, stride * channels);
 	if (dma_base == NULL) {
 		printk(KERN_ERR "dma failed to remap register block\n");
 		return -ENOMEM;
 	}
 
-	printk("Registering sysclass\n");
-
-	ret = sysdev_class_register(&dma_sysclass);
-	if (ret != 0) {
-		printk(KERN_ERR "dma sysclass registration failed\n");
-		goto err;
-	}
-
-	dma_kmem = kmem_cache_create("dma_desc", sizeof(struct s3c2410_dma_buf), 0,
+	dma_kmem = kmem_cache_create("dma_desc",
+				     sizeof(struct s3c2410_dma_buf), 0,
 				     SLAB_HWCACHE_ALIGN,
 				     s3c2410_dma_cache_ctor, NULL);
 
@@ -1310,15 +1342,15 @@ static int __init s3c2410_init_dma(void)
 		goto err;
 	}
 
-	for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) {
+	for (channel = 0; channel < channels;  channel++) {
 		cp = &s3c2410_chans[channel];
 
 		memset(cp, 0, sizeof(struct s3c2410_dma_chan));
 
 		/* dma channel irqs are in order.. */
 		cp->number = channel;
-		cp->irq    = channel + IRQ_DMA0;
-		cp->regs   = dma_base + (channel*0x40);
+		cp->irq    = channel + irq;
+		cp->regs   = dma_base + (channel * stride);
 
 		/* point current stats somewhere */
 		cp->stats  = &cp->stats_store;
@@ -1328,12 +1360,6 @@ static int __init s3c2410_init_dma(void)
 
 		cp->load_timeout = 1<<18;
 
-		/* register system device */
-
-		cp->dev.cls = &dma_sysclass;
-		cp->dev.id  = channel;
-		ret = sysdev_register(&cp->dev);
-
 		printk("DMA channel %d at %p, irq %d\n",
 		       cp->number, cp->regs, cp->irq);
 	}
@@ -1347,7 +1373,10 @@ static int __init s3c2410_init_dma(void)
 	return ret;
 }
 
-core_initcall(s3c2410_init_dma);
+int s3c2410_dma_init(void)
+{
+	return s3c24xx_dma_init(4, IRQ_DMA0, 0x40);
+}
 
 static inline int is_channel_valid(unsigned int channel)
 {
@@ -1384,7 +1413,7 @@ struct s3c2410_dma_chan *s3c2410_dma_map
 	if (dma_order) {
 		ord = &dma_order->channels[channel];
 
-		for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) {
+		for (ch = 0; ch < dma_channels; ch++) {
 			if (!is_channel_valid(ord->list[ch]))
 				continue;
 
@@ -1400,7 +1429,7 @@ struct s3c2410_dma_chan *s3c2410_dma_map
 
 	/* second, search the channel map for first free */
 
-	for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) {
+	for (ch = 0; ch < dma_channels; ch++) {
 		if (!is_channel_valid(ch_map->channels[ch]))
 			continue;
 
@@ -1410,7 +1439,7 @@ struct s3c2410_dma_chan *s3c2410_dma_map
 		}
 	}
 
-	if (ch >= S3C2410_DMA_CHANNELS)
+	if (ch >= dma_channels)
 		return NULL;
 
 	/* update our channel mapping */
diff -urpN -X linux-2.6.20-rmk-16feb2007-patch1/Documentation/dontdiff linux-2.6.20-rmk-16feb2007-patch1/arch/arm/mach-s3c2410/dma.c linux-2.6.20-rmk-16feb2007-s3c2443-2/arch/arm/mach-s3c2410/dma.c
--- linux-2.6.20-rmk-16feb2007-patch1/arch/arm/mach-s3c2410/dma.c	2007-02-16 17:18:36.000000000 +0000
+++ linux-2.6.20-rmk-16feb2007-s3c2443-2/arch/arm/mach-s3c2410/dma.c	2007-02-17 14:30:14.000000000 +0000
@@ -19,9 +19,9 @@
 
 #include <asm/dma.h>
 #include <asm/arch/dma.h>
-#include <asm/plat-s3c24xx/dma.h>
 
 #include <asm/plat-s3c24xx/cpu.h>
+#include <asm/plat-s3c24xx/dma.h>
 
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
@@ -147,6 +147,7 @@ static struct s3c24xx_dma_order __initda
 
 static int s3c2410_dma_add(struct sys_device *sysdev)
 {
+	s3c2410_dma_init();
 	s3c24xx_dma_order_set(&s3c2410_dma_order);
 	return s3c24xx_dma_init_map(&s3c2410_dma_sel);
 }
@@ -156,12 +157,12 @@ static struct sysdev_driver s3c2410_dma_
 	.add	= s3c2410_dma_add,
 };
 
-static int __init s3c2410_dma_init(void)
+static int __init s3c2410_dma_drvinit(void)
 {
 	return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
 }
 
-arch_initcall(s3c2410_dma_init);
+arch_initcall(s3c2410_dma_drvinit);
 #endif
 
 #if defined(CONFIG_CPU_S3C2442)
@@ -170,11 +171,11 @@ static struct sysdev_driver s3c2442_dma_
 	.add	= s3c2410_dma_add,
 };
 
-static int __init s3c2442_dma_init(void)
+static int __init s3c2442_dma_drvinit(void)
 {
 	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
 }
 
-arch_initcall(s3c2442_dma_init);
+arch_initcall(s3c2442_dma_drvinit);
 #endif
 
diff -urpN -X linux-2.6.20-rmk-16feb2007-patch1/Documentation/dontdiff linux-2.6.20-rmk-16feb2007-patch1/arch/arm/mach-s3c2412/dma.c linux-2.6.20-rmk-16feb2007-s3c2443-2/arch/arm/mach-s3c2412/dma.c
--- linux-2.6.20-rmk-16feb2007-patch1/arch/arm/mach-s3c2412/dma.c	2007-02-16 17:18:36.000000000 +0000
+++ linux-2.6.20-rmk-16feb2007-s3c2443-2/arch/arm/mach-s3c2412/dma.c	2007-02-17 14:19:55.000000000 +0000
@@ -146,6 +146,7 @@ static struct s3c24xx_dma_selection __in
 
 static int s3c2412_dma_add(struct sys_device *sysdev)
 {
+	s3c2410_dma_init();
 	return s3c24xx_dma_init_map(&s3c2412_dma_sel);
 }
 
diff -urpN -X linux-2.6.20-rmk-16feb2007-patch1/Documentation/dontdiff linux-2.6.20-rmk-16feb2007-patch1/arch/arm/mach-s3c2440/dma.c linux-2.6.20-rmk-16feb2007-s3c2443-2/arch/arm/mach-s3c2440/dma.c
--- linux-2.6.20-rmk-16feb2007-patch1/arch/arm/mach-s3c2440/dma.c	2007-02-16 17:18:36.000000000 +0000
+++ linux-2.6.20-rmk-16feb2007-s3c2443-2/arch/arm/mach-s3c2440/dma.c	2007-02-17 13:55:20.000000000 +0000
@@ -19,8 +19,8 @@
 
 #include <asm/dma.h>
 #include <asm/arch/dma.h>
-#include <asm/plat-s3c24xx/dma.h>
 
+#include <asm/plat-s3c24xx/dma.h>
 #include <asm/plat-s3c24xx/cpu.h>
 
 #include <asm/arch/regs-serial.h>
@@ -192,6 +192,7 @@ static struct s3c24xx_dma_order __initda
 
 static int s3c2440_dma_add(struct sys_device *sysdev)
 {
+	s3c2410_dma_init();
 	s3c24xx_dma_order_set(&s3c2440_dma_order);
 	return s3c24xx_dma_init_map(&s3c2440_dma_sel);
 }

