summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-s3c2410/dma.c11
-rw-r--r--arch/arm/mach-s3c2412/dma.c1
-rw-r--r--arch/arm/mach-s3c2440/dma.c3
-rw-r--r--arch/arm/plat-s3c24xx/dma.c77
-rw-r--r--include/asm-arm/plat-s3c24xx/dma.h7
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);
OpenPOWER on IntegriCloud