]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/plat-s3c24xx/dma.c
Pull bugzilla-8768 into release branch
[linux-2.6-omap-h63xx.git] / arch / arm / plat-s3c24xx / dma.c
index 929265aab7dd279807fdd2b495638c4cce9f16dd..6d048490c559ddcda21b7451584ca00609b97725 100644 (file)
@@ -42,7 +42,9 @@
 static void __iomem *dma_base;
 static struct kmem_cache *dma_kmem;
 
-struct s3c24xx_dma_selection dma_sel;
+static int dma_channels;
+
+static struct s3c24xx_dma_selection dma_sel;
 
 /* dma channel state information */
 struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
@@ -878,7 +880,7 @@ static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
        return 0;
 }
 
-void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
+static void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
 {
        unsigned long tmp;
        unsigned int timeout = 0x10000;
@@ -955,8 +957,7 @@ static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
        return 0;
 }
 
-int
-s3c2410_dma_started(struct s3c2410_dma_chan *chan)
+static int s3c2410_dma_started(struct s3c2410_dma_chan *chan)
 {
        unsigned long flags;
 
@@ -1152,7 +1153,7 @@ EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
  *
  * hwcfg:     the value for xxxSTCn register,
  *            bit 0: 0=increment pointer, 1=leave pointer
- *            bit 1: 0=soucre is AHB, 1=soucre is APB
+ *            bit 1: 0=source is AHB, 1=source is APB
  *
  * devaddr:   physical address of the source
 */
@@ -1278,7 +1279,42 @@ static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long
 
 /* initialisation code */
 
-static int __init s3c2410_init_dma(void)
+static 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);
+
+static 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,23 +1322,18 @@ 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);
+                                    s3c2410_dma_cache_ctor);
 
        if (dma_kmem == NULL) {
                printk(KERN_ERR "dma failed to make kmem cache\n");
@@ -1310,15 +1341,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 +1359,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 +1372,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)
 {
@@ -1367,7 +1395,7 @@ static struct s3c24xx_dma_order *dma_order;
  * channel
 */
 
-struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
+static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
 {
        struct s3c24xx_dma_order_ch *ord = NULL;
        struct s3c24xx_dma_map *ch_map;
@@ -1384,7 +1412,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 +1428,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 +1438,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 */