#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>
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);
}
.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)
.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
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 */
/* 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;
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);
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;
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);
}
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)
{
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;
/* 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;
}
}
- if (ch >= S3C2410_DMA_CHANNELS)
+ if (ch >= dma_channels)
return NULL;
/* update our channel mapping */