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