• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/cris/arch-v10/kernel/
1/* Wrapper for DMA channel allocator that updates DMA client muxing.
2 * Copyright 2004-2007, Axis Communications AB
3 */
4
5#include <linux/kernel.h>
6#include <linux/module.h>
7#include <linux/errno.h>
8
9#include <asm/dma.h>
10#include <arch/svinto.h>
11
12/* Macro to access ETRAX 100 registers */
13#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
14					  IO_STATE_(reg##_, field##_, _##val)
15
16
17static char used_dma_channels[MAX_DMA_CHANNELS];
18static const char * used_dma_channels_users[MAX_DMA_CHANNELS];
19
20int cris_request_dma(unsigned int dmanr, const char * device_id,
21		     unsigned options, enum dma_owner owner)
22{
23	unsigned long flags;
24	unsigned long int gens;
25	int fail = -EINVAL;
26
27	if (dmanr >= MAX_DMA_CHANNELS) {
28		printk(KERN_CRIT "cris_request_dma: invalid DMA channel %u\n", dmanr);
29		return -EINVAL;
30	}
31
32	local_irq_save(flags);
33	if (used_dma_channels[dmanr]) {
34		local_irq_restore(flags);
35		if (options & DMA_VERBOSE_ON_ERROR) {
36			printk(KERN_CRIT "Failed to request DMA %i for %s, already allocated by %s\n", dmanr, device_id, used_dma_channels_users[dmanr]);
37		}
38		if (options & DMA_PANIC_ON_ERROR) {
39			panic("request_dma error!");
40		}
41		return -EBUSY;
42	}
43
44	gens = genconfig_shadow;
45
46	switch(owner)
47	{
48	case dma_eth:
49		if ((dmanr != NETWORK_TX_DMA_NBR) &&
50		    (dmanr != NETWORK_RX_DMA_NBR)) {
51			printk(KERN_CRIT "Invalid DMA channel for eth\n");
52			goto bail;
53		}
54		break;
55	case dma_ser0:
56		if (dmanr == SER0_TX_DMA_NBR) {
57			SETS(gens, R_GEN_CONFIG, dma6, serial0);
58		} else if (dmanr == SER0_RX_DMA_NBR) {
59			SETS(gens, R_GEN_CONFIG, dma7, serial0);
60		} else {
61			printk(KERN_CRIT "Invalid DMA channel for ser0\n");
62			goto bail;
63		}
64		break;
65	case dma_ser1:
66		if (dmanr == SER1_TX_DMA_NBR) {
67			SETS(gens, R_GEN_CONFIG, dma8, serial1);
68		} else if (dmanr == SER1_RX_DMA_NBR) {
69			SETS(gens, R_GEN_CONFIG, dma9, serial1);
70		} else {
71			printk(KERN_CRIT "Invalid DMA channel for ser1\n");
72			goto bail;
73		}
74		break;
75	case dma_ser2:
76		if (dmanr == SER2_TX_DMA_NBR) {
77			SETS(gens, R_GEN_CONFIG, dma2, serial2);
78		} else if (dmanr == SER2_RX_DMA_NBR) {
79			SETS(gens, R_GEN_CONFIG, dma3, serial2);
80		} else {
81			printk(KERN_CRIT "Invalid DMA channel for ser2\n");
82			goto bail;
83		}
84		break;
85	case dma_ser3:
86		if (dmanr == SER3_TX_DMA_NBR) {
87			SETS(gens, R_GEN_CONFIG, dma4, serial3);
88		} else if (dmanr == SER3_RX_DMA_NBR) {
89			SETS(gens, R_GEN_CONFIG, dma5, serial3);
90		} else {
91			printk(KERN_CRIT "Invalid DMA channel for ser3\n");
92			goto bail;
93		}
94		break;
95	case dma_ata:
96		if (dmanr == ATA_TX_DMA_NBR) {
97			SETS(gens, R_GEN_CONFIG, dma2, ata);
98		} else if (dmanr == ATA_RX_DMA_NBR) {
99			SETS(gens, R_GEN_CONFIG, dma3, ata);
100		} else {
101			printk(KERN_CRIT "Invalid DMA channel for ata\n");
102			goto bail;
103		}
104		break;
105	case dma_ext0:
106		if (dmanr == EXTDMA0_TX_DMA_NBR) {
107			SETS(gens, R_GEN_CONFIG, dma4, extdma0);
108		} else if (dmanr == EXTDMA0_RX_DMA_NBR) {
109			SETS(gens, R_GEN_CONFIG, dma5, extdma0);
110		} else {
111			printk(KERN_CRIT "Invalid DMA channel for ext0\n");
112			goto bail;
113		}
114		break;
115	case dma_ext1:
116		if (dmanr == EXTDMA1_TX_DMA_NBR) {
117			SETS(gens, R_GEN_CONFIG, dma6, extdma1);
118		} else if (dmanr == EXTDMA1_RX_DMA_NBR) {
119			SETS(gens, R_GEN_CONFIG, dma7, extdma1);
120		} else {
121			printk(KERN_CRIT "Invalid DMA channel for ext1\n");
122			goto bail;
123		}
124		break;
125	case dma_int6:
126		if (dmanr == MEM2MEM_RX_DMA_NBR) {
127			SETS(gens, R_GEN_CONFIG, dma7, intdma6);
128		} else {
129			printk(KERN_CRIT "Invalid DMA channel for int6\n");
130			goto bail;
131		}
132		break;
133	case dma_int7:
134		if (dmanr == MEM2MEM_TX_DMA_NBR) {
135			SETS(gens, R_GEN_CONFIG, dma6, intdma7);
136		} else {
137			printk(KERN_CRIT "Invalid DMA channel for int7\n");
138			goto bail;
139		}
140		break;
141	case dma_usb:
142		if (dmanr == USB_TX_DMA_NBR) {
143			SETS(gens, R_GEN_CONFIG, dma8, usb);
144		} else if (dmanr == USB_RX_DMA_NBR) {
145			SETS(gens, R_GEN_CONFIG, dma9, usb);
146		} else {
147			printk(KERN_CRIT "Invalid DMA channel for usb\n");
148			goto bail;
149		}
150		break;
151	case dma_scsi0:
152		if (dmanr == SCSI0_TX_DMA_NBR) {
153			SETS(gens, R_GEN_CONFIG, dma2, scsi0);
154		} else if (dmanr == SCSI0_RX_DMA_NBR) {
155			SETS(gens, R_GEN_CONFIG, dma3, scsi0);
156		} else {
157			printk(KERN_CRIT "Invalid DMA channel for scsi0\n");
158			goto bail;
159		}
160		break;
161	case dma_scsi1:
162		if (dmanr == SCSI1_TX_DMA_NBR) {
163			SETS(gens, R_GEN_CONFIG, dma4, scsi1);
164		} else if (dmanr == SCSI1_RX_DMA_NBR) {
165			SETS(gens, R_GEN_CONFIG, dma5, scsi1);
166		} else {
167			printk(KERN_CRIT "Invalid DMA channel for scsi1\n");
168			goto bail;
169		}
170		break;
171	case dma_par0:
172		if (dmanr == PAR0_TX_DMA_NBR) {
173			SETS(gens, R_GEN_CONFIG, dma2, par0);
174		} else if (dmanr == PAR0_RX_DMA_NBR) {
175			SETS(gens, R_GEN_CONFIG, dma3, par0);
176		} else {
177			printk(KERN_CRIT "Invalid DMA channel for par0\n");
178			goto bail;
179		}
180		break;
181	case dma_par1:
182		if (dmanr == PAR1_TX_DMA_NBR) {
183			SETS(gens, R_GEN_CONFIG, dma4, par1);
184		} else if (dmanr == PAR1_RX_DMA_NBR) {
185			SETS(gens, R_GEN_CONFIG, dma5, par1);
186		} else {
187			printk(KERN_CRIT "Invalid DMA channel for par1\n");
188			goto bail;
189		}
190		break;
191	default:
192		printk(KERN_CRIT "Invalid DMA owner.\n");
193		goto bail;
194	}
195
196	used_dma_channels[dmanr] = 1;
197	used_dma_channels_users[dmanr] = device_id;
198
199	{
200		volatile int i;
201		genconfig_shadow = gens;
202		*R_GEN_CONFIG = genconfig_shadow;
203		/* Wait 12 cycles before doing any DMA command */
204		for(i = 6; i > 0; i--)
205			nop();
206	}
207	fail = 0;
208 bail:
209	local_irq_restore(flags);
210	return fail;
211}
212
213void cris_free_dma(unsigned int dmanr, const char * device_id)
214{
215	unsigned long flags;
216	if (dmanr >= MAX_DMA_CHANNELS) {
217		printk(KERN_CRIT "cris_free_dma: invalid DMA channel %u\n", dmanr);
218		return;
219	}
220
221	local_irq_save(flags);
222	if (!used_dma_channels[dmanr]) {
223		printk(KERN_CRIT "cris_free_dma: DMA channel %u not allocated\n", dmanr);
224	} else if (device_id != used_dma_channels_users[dmanr]) {
225		printk(KERN_CRIT "cris_free_dma: DMA channel %u not allocated by device\n", dmanr);
226	} else {
227		switch(dmanr)
228		{
229		case 0:
230			*R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, reset);
231			while (IO_EXTRACT(R_DMA_CH0_CMD, cmd, *R_DMA_CH0_CMD) ==
232			       IO_STATE_VALUE(R_DMA_CH0_CMD, cmd, reset));
233			break;
234		case 1:
235			*R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, reset);
236			while (IO_EXTRACT(R_DMA_CH1_CMD, cmd, *R_DMA_CH1_CMD) ==
237			       IO_STATE_VALUE(R_DMA_CH1_CMD, cmd, reset));
238			break;
239		case 2:
240			*R_DMA_CH2_CMD = IO_STATE(R_DMA_CH2_CMD, cmd, reset);
241			while (IO_EXTRACT(R_DMA_CH2_CMD, cmd, *R_DMA_CH2_CMD) ==
242			       IO_STATE_VALUE(R_DMA_CH2_CMD, cmd, reset));
243			break;
244		case 3:
245			*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, reset);
246			while (IO_EXTRACT(R_DMA_CH3_CMD, cmd, *R_DMA_CH3_CMD) ==
247			       IO_STATE_VALUE(R_DMA_CH3_CMD, cmd, reset));
248			break;
249		case 4:
250			*R_DMA_CH4_CMD = IO_STATE(R_DMA_CH4_CMD, cmd, reset);
251			while (IO_EXTRACT(R_DMA_CH4_CMD, cmd, *R_DMA_CH4_CMD) ==
252			       IO_STATE_VALUE(R_DMA_CH4_CMD, cmd, reset));
253			break;
254		case 5:
255			*R_DMA_CH5_CMD = IO_STATE(R_DMA_CH5_CMD, cmd, reset);
256			while (IO_EXTRACT(R_DMA_CH5_CMD, cmd, *R_DMA_CH5_CMD) ==
257			       IO_STATE_VALUE(R_DMA_CH5_CMD, cmd, reset));
258			break;
259		case 6:
260			*R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
261			while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *R_DMA_CH6_CMD) ==
262			       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
263			break;
264		case 7:
265			*R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, reset);
266			while (IO_EXTRACT(R_DMA_CH7_CMD, cmd, *R_DMA_CH7_CMD) ==
267			       IO_STATE_VALUE(R_DMA_CH7_CMD, cmd, reset));
268			break;
269		case 8:
270			*R_DMA_CH8_CMD = IO_STATE(R_DMA_CH8_CMD, cmd, reset);
271			while (IO_EXTRACT(R_DMA_CH8_CMD, cmd, *R_DMA_CH8_CMD) ==
272			       IO_STATE_VALUE(R_DMA_CH8_CMD, cmd, reset));
273			break;
274		case 9:
275			*R_DMA_CH9_CMD = IO_STATE(R_DMA_CH9_CMD, cmd, reset);
276			while (IO_EXTRACT(R_DMA_CH9_CMD, cmd, *R_DMA_CH9_CMD) ==
277			       IO_STATE_VALUE(R_DMA_CH9_CMD, cmd, reset));
278			break;
279		}
280		used_dma_channels[dmanr] = 0;
281	}
282	local_irq_restore(flags);
283}
284
285EXPORT_SYMBOL(cris_request_dma);
286EXPORT_SYMBOL(cris_free_dma);
287