1 /* 2 *参考arch/arm/mach-s3c24xx/dma-s3c2410.c 3 */ 4 #include5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #include 15 #include 16 #include 17 #include 18 #include 19 #include 20 #include 21 22 #define DMA_BASE 0x4b000000 23 #define BUFF_SIZE 512 24 25 static unsigned char *src_addr;//源 26 static unsigned char *dst_addr;//目的 27 static int major; 28 static dma_addr_t psrc_addr; 29 static dma_addr_t pdst_addr; 30 31 static struct class *dma_class; 32 static int dma_ok; 33 #define MEM_COPY_NO_DMA 0 34 #define MEM_COPY_BY_DMA 1 35 static DECLARE_WAIT_QUEUE_HEAD(dma_waitq); 36 37 struct dma_regs { 38 unsigned long disrc; 39 unsigned long disrcc; 40 unsigned long didst; 41 unsigned long didstc; 42 unsigned long dcon; 43 unsigned long dstat; 44 unsigned long dcsrc; 45 unsigned long dcdst; 46 unsigned long dmasktrig; 47 }; 48 49 static volatile struct dma_regs *dma_regs; 50 51 long dma_ioctl(struct file *file, unsigned int cmd, unsigned long dat) 52 { 53 int i; 54 memset(src_addr,0xaa,BUFF_SIZE); //从src开始的BUFF_SIZE空间每个字节都设置为0xaa 55 memset(dst_addr,0x55,BUFF_SIZE); 56 57 if(cmd == MEM_COPY_NO_DMA){ 58 for(i = 0; i < BUFF_SIZE; i++){ 59 dst_addr[i] = src_addr[i]; 60 } 61 if(0 == memcmp(src_addr,dst_addr,BUFF_SIZE)){ 62 printk("no dma transfer has finished!\n"); 63 }else{ 64 printk("no dma transfer failed!\n"); 65 } 66 }else if(cmd == MEM_COPY_BY_DMA){ 67 68 dma_ok = 0; 69 70 dma_regs->disrc = psrc_addr; 71 dma_regs->didst = pdst_addr; 72 dma_regs->dcon = (1<<30) | (1<<29) | (1<<27) | (BUFF_SIZE); 73 74 //启动DMA 75 dma_regs->dmasktrig = (1<<1) | (1<<0); 76 77 /*等待DMA传输完成*/ 78 wait_event_interruptible(dma_waitq, dma_ok); 79 80 if(0 == memcmp(src_addr,dst_addr,BUFF_SIZE)){ 81 printk("dma transfer has finished!\n"); 82 }else{ 83 printk("dma transfer failed!\n"); 84 } 85 86 } 87 return 0; 88 } 89 90 ssize_t dma_read(struct file *file, char __user *buff, size_t size, loff_t *loff) 91 { 92 int err; 93 err = copy_to_user(buff,dst_addr,size); 94 if(err){ 95 return -1; 96 } 97 return 1; 98 } 99 100 static struct file_operations dma_fop = {101 .owner = THIS_MODULE,102 .read = dma_read,103 .unlocked_ioctl = dma_ioctl,104 };105 106 irqreturn_t dma_irq(int irq, void *devid)107 {108 dma_ok = 1;109 wake_up_interruptible(&dma_waitq);110 return IRQ_HANDLED;111 }112 113 static int dma_drv_init(void)114 {115 116 dma_regs = ioremap(DMA_BASE,sizeof(struct dma_regs));117 118 src_addr = dma_alloc_writecombine(NULL,BUFF_SIZE, &psrc_addr,GFP_KERNEL);119 dst_addr = dma_alloc_writecombine(NULL,BUFF_SIZE, &pdst_addr,GFP_KERNEL);120 121 if(request_irq(IRQ_DMA0,dma_irq,0,"dma_irq",NULL)){122 printk("request dma irq failed!\n");123 free_irq(IRQ_DMA0,NULL);124 return -1;125 }126 127 major = register_chrdev(0, "dma-z", &dma_fop);128 dma_class = class_create(THIS_MODULE, "DMA");129 device_create(dma_class, NULL, MKDEV(major,0), NULL, "dma0");130 131 return 0;132 }133 134 static void dma_drv_exit(void)135 {136 device_destroy(dma_class,MKDEV(major,0));137 class_destroy(dma_class);138 free_irq(IRQ_DMA0,NULL);139 dma_free_writecombine(NULL, BUFF_SIZE,src_addr,psrc_addr);140 dma_free_writecombine(NULL, BUFF_SIZE,dst_addr,pdst_addr);141 iounmap(dma_regs);142 }143 144 module_init(dma_drv_init);145 module_exit(dma_drv_exit);146 147 MODULE_LICENSE("GPL");148 MODULE_AUTHOR("1653699780@qq.com");