]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - arch/cris/arch-v10/kernel/dma.c
Merge branch 'r6040' of git://git.kernel.org/pub/scm/linux/kernel/git/romieu/netdev...
[linux-2.6.git] / arch / cris / arch-v10 / kernel / dma.c
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 <asm/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
17 static char used_dma_channels[MAX_DMA_CHANNELS];
18 static const char * used_dma_channels_users[MAX_DMA_CHANNELS];
19
20 int 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 < 0) || (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
213 void cris_free_dma(unsigned int dmanr, const char * device_id)
214 {
215         unsigned long flags;
216         if ((dmanr < 0) || (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
285 EXPORT_SYMBOL(cris_request_dma);
286 EXPORT_SYMBOL(cris_free_dma);