patch-2.4.0-test5 linux/arch/arm/kernel/dma-rpc.c

Next file: linux/arch/arm/kernel/dma.c
Previous file: linux/arch/arm/kernel/dma-isa.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test4/linux/arch/arm/kernel/dma-rpc.c linux/arch/arm/kernel/dma-rpc.c
@@ -21,10 +21,6 @@
 
 #include "dma.h"
 
-static struct fiq_handler fh = {
-	name: "floppydma"
-};
-
 #if 0
 typedef enum {
 	dma_size_8	= 1,
@@ -51,7 +47,7 @@
 #define state_wait_a	1
 #define state_wait_b	2
 
-static void arch_get_next_sg(dmasg_t *sg, dma_t *dma)
+static void iomd_get_next_sg(dmasg_t *sg, dma_t *dma)
 {
 	unsigned long end, offset, flags = 0;
 
@@ -90,19 +86,19 @@
 	sg->length |= flags;
 }
 
-static inline void arch_setup_dma_a(dmasg_t *sg, dma_t *dma)
+static inline void iomd_setup_dma_a(dmasg_t *sg, dma_t *dma)
 {
 	outl_t(sg->address, dma->dma_base + CURA);
 	outl_t(sg->length, dma->dma_base + ENDA);
 }
 
-static inline void arch_setup_dma_b(dmasg_t *sg, dma_t *dma)
+static inline void iomd_setup_dma_b(dmasg_t *sg, dma_t *dma)
 {
 	outl_t(sg->address, dma->dma_base + CURB);
 	outl_t(sg->length, dma->dma_base + ENDB);
 }
 
-static void arch_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
+static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
 {
 	dma_t *dma = (dma_t *)dev_id;
 	unsigned int status = 0, no_buffer = dma->sg == NULL;
@@ -110,26 +106,26 @@
 	do {
 		switch (dma->state) {
 		case state_prog_a:
-			arch_get_next_sg(&dma->cur_sg, dma);
-			arch_setup_dma_a(&dma->cur_sg, dma);
+			iomd_get_next_sg(&dma->cur_sg, dma);
+			iomd_setup_dma_a(&dma->cur_sg, dma);
 			dma->state = state_wait_a;
 
 		case state_wait_a:
 			status = inb_t(dma->dma_base + ST);
 			switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
 			case DMA_ST_OFL|DMA_ST_INT:
-				arch_get_next_sg(&dma->cur_sg, dma);
-				arch_setup_dma_a(&dma->cur_sg, dma);
+				iomd_get_next_sg(&dma->cur_sg, dma);
+				iomd_setup_dma_a(&dma->cur_sg, dma);
 				break;
 
 			case DMA_ST_INT:
-				arch_get_next_sg(&dma->cur_sg, dma);
-				arch_setup_dma_b(&dma->cur_sg, dma);
+				iomd_get_next_sg(&dma->cur_sg, dma);
+				iomd_setup_dma_b(&dma->cur_sg, dma);
 				dma->state = state_wait_b;
 				break;
 
 			case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB:
-				arch_setup_dma_b(&dma->cur_sg, dma);
+				iomd_setup_dma_b(&dma->cur_sg, dma);
 				dma->state = state_wait_b;
 				break;
 			}
@@ -139,18 +135,18 @@
 			status = inb_t(dma->dma_base + ST);
 			switch (status & (DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB)) {
 			case DMA_ST_OFL|DMA_ST_INT|DMA_ST_AB:
-				arch_get_next_sg(&dma->cur_sg, dma);
-				arch_setup_dma_b(&dma->cur_sg, dma);
+				iomd_get_next_sg(&dma->cur_sg, dma);
+				iomd_setup_dma_b(&dma->cur_sg, dma);
 				break;
 
 			case DMA_ST_INT|DMA_ST_AB:
-				arch_get_next_sg(&dma->cur_sg, dma);
-				arch_setup_dma_a(&dma->cur_sg, dma);
+				iomd_get_next_sg(&dma->cur_sg, dma);
+				iomd_setup_dma_a(&dma->cur_sg, dma);
 				dma->state = state_wait_a;
 				break;
 
 			case DMA_ST_OFL|DMA_ST_INT:
-				arch_setup_dma_a(&dma->cur_sg, dma);
+				iomd_setup_dma_a(&dma->cur_sg, dma);
 				dma->state = state_wait_a;
 				break;
 			}
@@ -162,167 +158,56 @@
 		disable_irq(irq);
 }
 
-int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_name)
+static int iomd_request_dma(dmach_t channel, dma_t *dma)
 {
 	unsigned long flags;
 	int ret;
 
-	switch (channel) {
-	case DMA_0:
-	case DMA_1:
-	case DMA_2:
-	case DMA_3:
-	case DMA_S0:
-	case DMA_S1:
-		save_flags_cli(flags);
-		ret = request_irq(dma->dma_irq, arch_dma_handle,
-				  SA_INTERRUPT, dev_name, dma);
-		if (!ret)
-			disable_irq(dma->dma_irq);
-		restore_flags(flags);
-		break;
-
-	case DMA_VIRTUAL_FLOPPY:
-	case DMA_VIRTUAL_SOUND:
-		ret = 0;
-		break;
-
-	default:
-		ret = -EINVAL;
-		break;
-	}
+	save_flags_cli(flags);
+	ret = request_irq(dma->dma_irq, iomd_dma_handle,
+			  SA_INTERRUPT, dma->device_id, dma);
+	if (!ret)
+		disable_irq(dma->dma_irq);
+	restore_flags(flags);
 
 	return ret;
 }
 
-void arch_free_dma(dmach_t channel, dma_t *dma)
+static void iomd_free_dma(dmach_t channel, dma_t *dma)
 {
-	switch (channel) {
-	case DMA_0:
-	case DMA_1:
-	case DMA_2:
-	case DMA_3:
-	case DMA_S0:
-	case DMA_S1:
-		free_irq(dma->dma_irq, dma);
-		break;
-
-	default:
-		break;
-	}
-}
-
-int arch_get_dma_residue(dmach_t channel, dma_t *dma)
-{
-	int residue = 0;
-
-	switch (channel) {
-	case DMA_0:	/* Physical DMA channels */
-	case DMA_1:
-	case DMA_2:
-	case DMA_3:
-	case DMA_S0:
-	case DMA_S1:
-		break;
-
-	case DMA_VIRTUAL_FLOPPY: {
-		struct pt_regs regs;
-		get_fiq_regs(&regs);
-		return regs.ARM_r9;
-		}
-		break;
-	}
-	return residue;
+	free_irq(dma->dma_irq, dma);
 }
 
-void arch_enable_dma(dmach_t channel, dma_t *dma)
+static void iomd_enable_dma(dmach_t channel, dma_t *dma)
 {
 	unsigned long dma_base = dma->dma_base;
-	unsigned int ctrl;
-
-	switch (channel) {
-	case DMA_0:	/* Physical DMA channels */
-	case DMA_1:
-	case DMA_2:
-	case DMA_3:
-	case DMA_S0:
-	case DMA_S1:
-		ctrl = TRANSFER_SIZE | DMA_CR_E;
+	unsigned int ctrl = TRANSFER_SIZE | DMA_CR_E;
 
-		if (dma->invalid) {
-			dma->invalid = 0;
+	if (dma->invalid) {
+		dma->invalid = 0;
 
-			outb_t(DMA_CR_C, dma_base + CR);
-			dma->state = state_prog_a;
-		}
+		outb_t(DMA_CR_C, dma_base + CR);
+		dma->state = state_prog_a;
+	}
 		
-		if (dma->dma_mode == DMA_MODE_READ)
-			ctrl |= DMA_CR_D;
+	if (dma->dma_mode == DMA_MODE_READ)
+		ctrl |= DMA_CR_D;
 
-		outb_t(ctrl, dma_base + CR);
-		enable_irq(dma->dma_irq);
-		break;
-
-	case DMA_VIRTUAL_FLOPPY: {
-		void *fiqhandler_start;
-		unsigned int fiqhandler_length;
-		struct pt_regs regs;
-
-		if (dma->dma_mode == DMA_MODE_READ) {
-			extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
-			fiqhandler_start = &floppy_fiqin_start;
-			fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
-		} else {
-			extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
-			fiqhandler_start = &floppy_fiqout_start;
-			fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
-		}
-
-		regs.ARM_r9  = dma->buf.length;
-		regs.ARM_r10 = __bus_to_virt(dma->buf.address);
-		regs.ARM_fp  = (int)PCIO_FLOPPYDMABASE;
-
-		if (claim_fiq(&fh)) {
-			printk("floppydma: couldn't claim FIQ.\n");
-			return;
-		}
-
-		set_fiq_handler(fiqhandler_start, fiqhandler_length);
-		set_fiq_regs(&regs);
-		enable_irq(dma->dma_irq);
-		}
-		break;
-
-	default:
-		break;
-	}
+	outb_t(ctrl, dma_base + CR);
+	enable_irq(dma->dma_irq);
 }
 
-void arch_disable_dma(dmach_t channel, dma_t *dma)
+static void iomd_disable_dma(dmach_t channel, dma_t *dma)
 {
 	unsigned long dma_base = dma->dma_base;
 	unsigned int ctrl;
 
-	switch (channel) {
-	case DMA_0:	/* Physical DMA channels */
-	case DMA_1:
-	case DMA_2:
-	case DMA_3:
-	case DMA_S0:
-	case DMA_S1:
-		disable_irq(dma->dma_irq);
-		ctrl = inb_t(dma_base + CR);
-		outb_t(ctrl & ~DMA_CR_E, dma_base + CR);
-		break;
-
-	case DMA_VIRTUAL_FLOPPY:
-		disable_irq(dma->dma_irq);
-		release_fiq(&fh);
-		break;
-	}
+	disable_irq(dma->dma_irq);
+	ctrl = inb_t(dma_base + CR);
+	outb_t(ctrl & ~DMA_CR_E, dma_base + CR);
 }
 
-int arch_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
+static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
 {
 	int tcr, speed;
 
@@ -364,6 +249,82 @@
 	return speed;
 }
 
+static struct dma_ops iomd_dma_ops = {
+	type:		"IOMD",
+	request:	iomd_request_dma,
+	free:		iomd_free_dma,
+	enable:		iomd_enable_dma,
+	disable:	iomd_disable_dma,
+	setspeed:	iomd_set_dma_speed,
+};
+
+static struct fiq_handler fh = {
+	name: "floppydma"
+};
+
+static void floppy_enable_dma(dmach_t channel, dma_t *dma)
+{
+	void *fiqhandler_start;
+	unsigned int fiqhandler_length;
+	struct pt_regs regs;
+
+	if (dma->dma_mode == DMA_MODE_READ) {
+		extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
+		fiqhandler_start = &floppy_fiqin_start;
+		fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
+	} else {
+		extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
+		fiqhandler_start = &floppy_fiqout_start;
+		fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
+	}
+
+	regs.ARM_r9  = dma->buf.length;
+	regs.ARM_r10 = __bus_to_virt(dma->buf.address);
+	regs.ARM_fp  = (int)PCIO_FLOPPYDMABASE;
+
+	if (claim_fiq(&fh)) {
+		printk("floppydma: couldn't claim FIQ.\n");
+		return;
+	}
+
+	set_fiq_handler(fiqhandler_start, fiqhandler_length);
+	set_fiq_regs(&regs);
+	enable_irq(dma->dma_irq);
+}
+
+static void floppy_disable_dma(dmach_t channel, dma_t *dma)
+{
+	disable_irq(dma->dma_irq);
+	release_fiq(&fh);
+}
+
+static int floppy_get_residue(dmach_t channel, dma_t *dma)
+{
+	struct pt_regs regs;
+	get_fiq_regs(&regs);
+	return regs.ARM_r9;
+}
+
+static struct dma_ops floppy_dma_ops = {
+	type:		"FIQDMA",
+	enable:		floppy_enable_dma,
+	disable:	floppy_disable_dma,
+	residue:	floppy_get_residue,
+};
+
+/*
+ * This is virtual DMA - we don't need anything here.
+ */
+static int sound_enable_disable_dma(dmach_t channel, dma_t *dma)
+{
+}
+
+static struct dma_ops sound_dma_ops = {
+	type:		"VIRTUAL",
+	enable:		sound_enable_disable_dma,
+	disable:	sound_enable_disable_dma,
+};
+
 void __init arch_dma_init(dma_t *dma)
 {
 	outb(0, IOMD_IO0CR);
@@ -373,21 +334,30 @@
 
 	outb(0xa0, IOMD_DMATCR);
 
-	dma[0].dma_base = ioaddr(IOMD_IO0CURA);
-	dma[0].dma_irq  = IRQ_DMA0;
-	dma[1].dma_base = ioaddr(IOMD_IO1CURA);
-	dma[1].dma_irq  = IRQ_DMA1;
-	dma[2].dma_base = ioaddr(IOMD_IO2CURA);
-	dma[2].dma_irq  = IRQ_DMA2;
-	dma[3].dma_base = ioaddr(IOMD_IO3CURA);
-	dma[3].dma_irq  = IRQ_DMA3;
-	dma[4].dma_base = ioaddr(IOMD_SD0CURA);
-	dma[4].dma_irq  = IRQ_DMAS0;
-	dma[5].dma_base = ioaddr(IOMD_SD1CURA);
-	dma[5].dma_irq  = IRQ_DMAS1;
-	dma[6].dma_irq  = 64;
+	dma[DMA_0].dma_base		= ioaddr(IOMD_IO0CURA);
+	dma[DMA_0].dma_irq		= IRQ_DMA0;
+	dma[DMA_0].d_ops		= &iomd_dma_ops;
+	dma[DMA_1].dma_base		= ioaddr(IOMD_IO1CURA);
+	dma[DMA_1].dma_irq		= IRQ_DMA1;
+	dma[DMA_1].d_ops		= &iomd_dma_ops;
+	dma[DMA_2].dma_base		= ioaddr(IOMD_IO2CURA);
+	dma[DMA_2].dma_irq		= IRQ_DMA2;
+	dma[DMA_2].d_ops		= &iomd_dma_ops;
+	dma[DMA_3].dma_base		= ioaddr(IOMD_IO3CURA);
+	dma[DMA_3].dma_irq		= IRQ_DMA3;
+	dma[DMA_3].d_ops		= &iomd_dma_ops;
+	dma[DMA_S0].dma_base		= ioaddr(IOMD_SD0CURA);
+	dma[DMA_S0].dma_irq		= IRQ_DMAS0;
+	dma[DMA_S0].d_ops		= &iomd_dma_ops;
+	dma[DMA_S1].dma_base		= ioaddr(IOMD_SD1CURA);
+	dma[DMA_S1].dma_irq		= IRQ_DMAS1;
+	dma[DMA_S1].d_ops		= &iomd_dma_ops;
+	dma[DMA_VIRTUAL_FLOPPY].dma_irq	= 64;
+	dma[DMA_VIRTUAL_FLOPPY].d_ops	= &floppy_dma_ops;
+	dma[DMA_VIRTUAL_SOUND].d_ops	= &sound_dma_ops;
 
-	/* Setup DMA channels 2,3 to be for podules
+	/*
+	 * Setup DMA channels 2,3 to be for podules
 	 * and channels 0,1 for internal devices
 	 */
 	outb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)