1 /* 2 * linux/arch/arm/kernel/dma.c 3 * 4 * Copyright (C) 1995-2000 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Front-end to the DMA handling. This handles the allocation/freeing 11 * of DMA channels, and provides a unified interface to the machines 12 * DMA facilities. 13 */ 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/spinlock.h> 17 #include <linux/errno.h> 18 #include <linux/scatterlist.h> 19 #include <linux/seq_file.h> 20 #include <linux/proc_fs.h> 21 22 #include <asm/dma.h> 23 24 #include <asm/mach/dma.h> 25 26 DEFINE_SPINLOCK(dma_spin_lock); 27 EXPORT_SYMBOL(dma_spin_lock); 28 29 static dma_t *dma_chan[MAX_DMA_CHANNELS]; 30 31 static inline dma_t *dma_channel(unsigned int chan) 32 { 33 if (chan >= MAX_DMA_CHANNELS) 34 return NULL; 35 36 return dma_chan[chan]; 37 } 38 39 int __init isa_dma_add(unsigned int chan, dma_t *dma) 40 { 41 if (!dma->d_ops) 42 return -EINVAL; 43 44 sg_init_table(&dma->buf, 1); 45 46 if (dma_chan[chan]) 47 return -EBUSY; 48 dma_chan[chan] = dma; 49 return 0; 50 } 51 52 /* 53 * Request DMA channel 54 * 55 * On certain platforms, we have to allocate an interrupt as well... 56 */ 57 int request_dma(unsigned int chan, const char *device_id) 58 { 59 dma_t *dma = dma_channel(chan); 60 int ret; 61 62 if (!dma) 63 goto bad_dma; 64 65 if (xchg(&dma->lock, 1) != 0) 66 goto busy; 67 68 dma->device_id = device_id; 69 dma->active = 0; 70 dma->invalid = 1; 71 72 ret = 0; 73 if (dma->d_ops->request) 74 ret = dma->d_ops->request(chan, dma); 75 76 if (ret) 77 xchg(&dma->lock, 0); 78 79 return ret; 80 81 bad_dma: 82 printk(KERN_ERR "dma: trying to allocate DMA%d\n", chan); 83 return -EINVAL; 84 85 busy: 86 return -EBUSY; 87 } 88 EXPORT_SYMBOL(request_dma); 89 90 /* 91 * Free DMA channel 92 * 93 * On certain platforms, we have to free interrupt as well... 94 */ 95 void free_dma(unsigned int chan) 96 { 97 dma_t *dma = dma_channel(chan); 98 99 if (!dma) 100 goto bad_dma; 101 102 if (dma->active) { 103 printk(KERN_ERR "dma%d: freeing active DMA\n", chan); 104 dma->d_ops->disable(chan, dma); 105 dma->active = 0; 106 } 107 108 if (xchg(&dma->lock, 0) != 0) { 109 if (dma->d_ops->free) 110 dma->d_ops->free(chan, dma); 111 return; 112 } 113 114 printk(KERN_ERR "dma%d: trying to free free DMA\n", chan); 115 return; 116 117 bad_dma: 118 printk(KERN_ERR "dma: trying to free DMA%d\n", chan); 119 } 120 EXPORT_SYMBOL(free_dma); 121 122 /* Set DMA Scatter-Gather list 123 */ 124 void set_dma_sg (unsigned int chan, struct scatterlist *sg, int nr_sg) 125 { 126 dma_t *dma = dma_channel(chan); 127 128 if (dma->active) 129 printk(KERN_ERR "dma%d: altering DMA SG while " 130 "DMA active\n", chan); 131 132 dma->sg = sg; 133 dma->sgcount = nr_sg; 134 dma->invalid = 1; 135 } 136 EXPORT_SYMBOL(set_dma_sg); 137 138 /* Set DMA address 139 * 140 * Copy address to the structure, and set the invalid bit 141 */ 142 void __set_dma_addr (unsigned int chan, void *addr) 143 { 144 dma_t *dma = dma_channel(chan); 145 146 if (dma->active) 147 printk(KERN_ERR "dma%d: altering DMA address while " 148 "DMA active\n", chan); 149 150 dma->sg = NULL; 151 dma->addr = addr; 152 dma->invalid = 1; 153 } 154 EXPORT_SYMBOL(__set_dma_addr); 155 156 /* Set DMA byte count 157 * 158 * Copy address to the structure, and set the invalid bit 159 */ 160 void set_dma_count (unsigned int chan, unsigned long count) 161 { 162 dma_t *dma = dma_channel(chan); 163 164 if (dma->active) 165 printk(KERN_ERR "dma%d: altering DMA count while " 166 "DMA active\n", chan); 167 168 dma->sg = NULL; 169 dma->count = count; 170 dma->invalid = 1; 171 } 172 EXPORT_SYMBOL(set_dma_count); 173 174 /* Set DMA direction mode 175 */ 176 void set_dma_mode (unsigned int chan, unsigned int mode) 177 { 178 dma_t *dma = dma_channel(chan); 179 180 if (dma->active) 181 printk(KERN_ERR "dma%d: altering DMA mode while " 182 "DMA active\n", chan); 183 184 dma->dma_mode = mode; 185 dma->invalid = 1; 186 } 187 EXPORT_SYMBOL(set_dma_mode); 188 189 /* Enable DMA channel 190 */ 191 void enable_dma (unsigned int chan) 192 { 193 dma_t *dma = dma_channel(chan); 194 195 if (!dma->lock) 196 goto free_dma; 197 198 if (dma->active == 0) { 199 dma->active = 1; 200 dma->d_ops->enable(chan, dma); 201 } 202 return; 203 204 free_dma: 205 printk(KERN_ERR "dma%d: trying to enable free DMA\n", chan); 206 BUG(); 207 } 208 EXPORT_SYMBOL(enable_dma); 209 210 /* Disable DMA channel 211 */ 212 void disable_dma (unsigned int chan) 213 { 214 dma_t *dma = dma_channel(chan); 215 216 if (!dma->lock) 217 goto free_dma; 218 219 if (dma->active == 1) { 220 dma->active = 0; 221 dma->d_ops->disable(chan, dma); 222 } 223 return; 224 225 free_dma: 226 printk(KERN_ERR "dma%d: trying to disable free DMA\n", chan); 227 BUG(); 228 } 229 EXPORT_SYMBOL(disable_dma); 230 231 /* 232 * Is the specified DMA channel active? 233 */ 234 int dma_channel_active(unsigned int chan) 235 { 236 dma_t *dma = dma_channel(chan); 237 return dma->active; 238 } 239 EXPORT_SYMBOL(dma_channel_active); 240 241 void set_dma_page(unsigned int chan, char pagenr) 242 { 243 printk(KERN_ERR "dma%d: trying to set_dma_page\n", chan); 244 } 245 EXPORT_SYMBOL(set_dma_page); 246 247 void set_dma_speed(unsigned int chan, int cycle_ns) 248 { 249 dma_t *dma = dma_channel(chan); 250 int ret = 0; 251 252 if (dma->d_ops->setspeed) 253 ret = dma->d_ops->setspeed(chan, dma, cycle_ns); 254 dma->speed = ret; 255 } 256 EXPORT_SYMBOL(set_dma_speed); 257 258 int get_dma_residue(unsigned int chan) 259 { 260 dma_t *dma = dma_channel(chan); 261 int ret = 0; 262 263 if (dma->d_ops->residue) 264 ret = dma->d_ops->residue(chan, dma); 265 266 return ret; 267 } 268 EXPORT_SYMBOL(get_dma_residue); 269 270 #ifdef CONFIG_PROC_FS 271 static int proc_dma_show(struct seq_file *m, void *v) 272 { 273 int i; 274 275 for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) { 276 dma_t *dma = dma_channel(i); 277 if (dma && dma->lock) 278 seq_printf(m, "%2d: %s\n", i, dma->device_id); 279 } 280 return 0; 281 } 282 283 static int proc_dma_open(struct inode *inode, struct file *file) 284 { 285 return single_open(file, proc_dma_show, NULL); 286 } 287 288 static const struct file_operations proc_dma_operations = { 289 .open = proc_dma_open, 290 .read = seq_read, 291 .llseek = seq_lseek, 292 .release = single_release, 293 }; 294 295 static int __init proc_dma_init(void) 296 { 297 proc_create("dma", 0, NULL, &proc_dma_operations); 298 return 0; 299 } 300 301 __initcall(proc_dma_init); 302 #endif 303