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