Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=48adbcf33b6087727a2db0b517c994a7ecfbeb0c
Commit:     48adbcf33b6087727a2db0b517c994a7ecfbeb0c
Parent:     15e4db7b8054ac171de946b9511655446dd29b8f
Author:     Ben Dooks <[EMAIL PROTECTED]>
AuthorDate: Sat Feb 17 15:37:14 2007 +0100
Committer:  Russell King <[EMAIL PROTECTED]>
CommitDate: Sat Feb 17 15:00:34 2007 +0000

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: Russell King <[EMAIL PROTECTED]>
---
 arch/arm/mach-s3c2410/dma.c        |   11 +++--
 arch/arm/mach-s3c2412/dma.c        |    1 +
 arch/arm/mach-s3c2440/dma.c        |    3 +-
 arch/arm/plat-s3c24xx/dma.c        |   77 ++++++++++++++++++++++++-----------
 include/asm-arm/plat-s3c24xx/dma.h |    7 +++
 5 files changed, 69 insertions(+), 30 deletions(-)

diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index 6b34526..67d1ad3 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -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 __initdata 
s3c2410_dma_order = {
 
 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_driver = {
        .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_driver = {
        .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 --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index 28b5982..d0f4695 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -146,6 +146,7 @@ static struct s3c24xx_dma_selection __initdata 
s3c2412_dma_sel = {
 
 static int s3c2412_dma_add(struct sys_device *sysdev)
 {
+       s3c2410_dma_init();
        return s3c24xx_dma_init_map(&s3c2412_dma_sel);
 }
 
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c
index 2bb2926..cd035a3 100644
--- a/arch/arm/mach-s3c2440/dma.c
+++ b/arch/arm/mach-s3c2440/dma.c
@@ -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 __initdata 
s3c2440_dma_order = {
 
 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);
 }
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 929265a..4540a80 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -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 *p, struct 
kmem_cache *c, unsigned long
 
 /* 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_channel(int 
channel)
        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_channel(int 
channel)
 
        /* 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_channel(int 
channel)
                }
        }
 
-       if (ch >= S3C2410_DMA_CHANNELS)
+       if (ch >= dma_channels)
                return NULL;
 
        /* update our channel mapping */
diff --git a/include/asm-arm/plat-s3c24xx/dma.h 
b/include/asm-arm/plat-s3c24xx/dma.h
index 15e140c..2c59406 100644
--- a/include/asm-arm/plat-s3c24xx/dma.h
+++ b/include/asm-arm/plat-s3c24xx/dma.h
@@ -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);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to