summaryrefslogtreecommitdiff
path: root/arch/arm/plat-s3c24xx/dma.c
diff options
context:
space:
mode:
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 @@
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 */