diff options
Diffstat (limited to 'arch/arm/kernel/dma-isa.c')
| -rw-r--r-- | arch/arm/kernel/dma-isa.c | 67 | 
1 files changed, 34 insertions, 33 deletions
| diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c index 4a3a50495c60..0e88e46fc732 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); +		}  	}  } |