summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/dma-isa.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-28 14:03:14 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-28 14:03:14 -0700
commit0fe41b8982001cd14ee2c77cd776735a5024e98b (patch)
tree83e65d595c413d55259ea14fb97748ce5efe5707 /arch/arm/kernel/dma-isa.c
parenteedf2c5296a8dfaaf9aec1a938c1d3bd73159a30 (diff)
parent9759d22c8348343b0da4e25d6150c41712686c14 (diff)
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (422 commits) [ARM] 5435/1: fix compile warning in sanity_check_meminfo() [ARM] 5434/1: ARM: OMAP: Fix mailbox compile for 24xx [ARM] pxa: fix the bad assumption that PCMCIA sockets always start with 0 [ARM] pxa: fix Colibri PXA300 and PXA320 LCD backlight pins imxfb: Fix TFT mode i.MX21/27: remove ifdef CONFIG_FB_IMX imxfb: add clock support mxc: add arch_reset() function clkdev: add possibility to get a clock based on the device name i.MX1: remove fb support from mach-imx [ARM] pxa: build arch/arm/plat-pxa/mfp.c only when PXA3xx or ARCH_MMP defined Gemini: Add support for Teltonika RUT100 Gemini: gpiolib based GPIO support v2 MAINTAINERS: add myself as Gemini architecture maintainer ARM: Add Gemini architecture v3 [ARM] OMAP: Fix compile for omap2_init_common_hw() MAINTAINERS: Add myself as Faraday ARM core variant maintainer ARM: Add support for FA526 v2 [ARM] acorn,ebsa110,footbridge,integrator,sa1100: Convert asm/io.h to linux/io.h [ARM] collie: fix two minor formatting nits ...
Diffstat (limited to 'arch/arm/kernel/dma-isa.c')
-rw-r--r--arch/arm/kernel/dma-isa.c67
1 files changed, 34 insertions, 33 deletions
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index 4a3a50495c6..0e88e46fc73 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -24,11 +24,6 @@
#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);
+ }
}
}