Merge branch 'fix/asoc' into for-linus
[pandora-kernel.git] / arch / arm / kernel / dma-isa.c
index 4a3a504..0e88e46 100644 (file)
 #include <asm/dma.h>
 #include <asm/mach/dma.h>
 
-#define ISA_DMA_MODE_READ      0x44
-#define ISA_DMA_MODE_WRITE     0x48
-#define ISA_DMA_MODE_CASCADE   0xc0
-#define ISA_DMA_AUTOINIT       0x10
-
 #define ISA_DMA_MASK           0
 #define ISA_DMA_MODE           1
 #define ISA_DMA_CLRFF          2
@@ -49,38 +44,35 @@ static unsigned int isa_dma_port[8][7] = {
        {  0xd4,  0xd6,  0xd8,  0x48a,  0x08a,  0xcc, 0xce }
 };
 
-static int isa_get_dma_residue(dmach_t channel, dma_t *dma)
+static int isa_get_dma_residue(unsigned int chan, dma_t *dma)
 {
-       unsigned int io_port = isa_dma_port[channel][ISA_DMA_COUNT];
+       unsigned int io_port = isa_dma_port[chan][ISA_DMA_COUNT];
        int count;
 
        count = 1 + inb(io_port);
        count |= inb(io_port) << 8;
 
-       return channel < 4 ? count : (count << 1);
+       return chan < 4 ? count : (count << 1);
 }
 
-static void isa_enable_dma(dmach_t channel, dma_t *dma)
+static void isa_enable_dma(unsigned int chan, dma_t *dma)
 {
        if (dma->invalid) {
                unsigned long address, length;
                unsigned int mode;
                enum dma_data_direction direction;
 
-               mode = channel & 3;
+               mode = (chan & 3) | dma->dma_mode;
                switch (dma->dma_mode & DMA_MODE_MASK) {
                case DMA_MODE_READ:
-                       mode |= ISA_DMA_MODE_READ;
                        direction = DMA_FROM_DEVICE;
                        break;
 
                case DMA_MODE_WRITE:
-                       mode |= ISA_DMA_MODE_WRITE;
                        direction = DMA_TO_DEVICE;
                        break;
 
                case DMA_MODE_CASCADE:
-                       mode |= ISA_DMA_MODE_CASCADE;
                        direction = DMA_BIDIRECTIONAL;
                        break;
 
@@ -105,34 +97,31 @@ static void isa_enable_dma(dmach_t channel, dma_t *dma)
                address = dma->buf.dma_address;
                length  = dma->buf.length - 1;
 
-               outb(address >> 16, isa_dma_port[channel][ISA_DMA_PGLO]);
-               outb(address >> 24, isa_dma_port[channel][ISA_DMA_PGHI]);
+               outb(address >> 16, isa_dma_port[chan][ISA_DMA_PGLO]);
+               outb(address >> 24, isa_dma_port[chan][ISA_DMA_PGHI]);
 
-               if (channel >= 4) {
+               if (chan >= 4) {
                        address >>= 1;
                        length >>= 1;
                }
 
-               outb(0, isa_dma_port[channel][ISA_DMA_CLRFF]);
-
-               outb(address, isa_dma_port[channel][ISA_DMA_ADDR]);
-               outb(address >> 8, isa_dma_port[channel][ISA_DMA_ADDR]);
+               outb(0, isa_dma_port[chan][ISA_DMA_CLRFF]);
 
-               outb(length, isa_dma_port[channel][ISA_DMA_COUNT]);
-               outb(length >> 8, isa_dma_port[channel][ISA_DMA_COUNT]);
+               outb(address, isa_dma_port[chan][ISA_DMA_ADDR]);
+               outb(address >> 8, isa_dma_port[chan][ISA_DMA_ADDR]);
 
-               if (dma->dma_mode & DMA_AUTOINIT)
-                       mode |= ISA_DMA_AUTOINIT;
+               outb(length, isa_dma_port[chan][ISA_DMA_COUNT]);
+               outb(length >> 8, isa_dma_port[chan][ISA_DMA_COUNT]);
 
-               outb(mode, isa_dma_port[channel][ISA_DMA_MODE]);
+               outb(mode, isa_dma_port[chan][ISA_DMA_MODE]);
                dma->invalid = 0;
        }
-       outb(channel & 3, isa_dma_port[channel][ISA_DMA_MASK]);
+       outb(chan & 3, isa_dma_port[chan][ISA_DMA_MASK]);
 }
 
-static void isa_disable_dma(dmach_t channel, dma_t *dma)
+static void isa_disable_dma(unsigned int chan, dma_t *dma)
 {
-       outb(channel | 4, isa_dma_port[channel][ISA_DMA_MASK]);
+       outb(chan | 4, isa_dma_port[chan][ISA_DMA_MASK]);
 }
 
 static struct dma_ops isa_dma_ops = {
@@ -160,7 +149,12 @@ static struct resource dma_resources[] = { {
        .end    = 0x048f
 } };
 
-void __init isa_init_dma(dma_t *dma)
+static dma_t isa_dma[8];
+
+/*
+ * ISA DMA always starts at channel 0
+ */
+void __init isa_init_dma(void)
 {
        /*
         * Try to autodetect presence of an ISA DMA controller.
@@ -178,11 +172,11 @@ void __init isa_init_dma(dma_t *dma)
        outb(0xaa, 0x00);
 
        if (inb(0) == 0x55 && inb(0) == 0xaa) {
-               int channel, i;
+               unsigned int chan, i;
 
-               for (channel = 0; channel < 8; channel++) {
-                       dma[channel].d_ops = &isa_dma_ops;
-                       isa_disable_dma(channel, NULL);
+               for (chan = 0; chan < 8; chan++) {
+                       isa_dma[chan].d_ops = &isa_dma_ops;
+                       isa_disable_dma(chan, NULL);
                }
 
                outb(0x40, 0x0b);
@@ -217,5 +211,12 @@ void __init isa_init_dma(dma_t *dma)
 
                for (i = 0; i < ARRAY_SIZE(dma_resources); i++)
                        request_resource(&ioport_resource, dma_resources + i);
+
+               for (chan = 0; chan < 8; chan++) {
+                       int ret = isa_dma_add(chan, &isa_dma[chan]);
+                       if (ret)
+                               printk(KERN_ERR "ISADMA%u: unable to register: %d\n",
+                                       chan, ret);
+               }
        }
 }