IPMUX1IPMUX2IPMUX3: opl_cpuif.c源文件

RTL96xx (RTL9607,...)

opl_cpuif.c

浏览该文件的文档。
00001 
00015 #include <linux/init.h>
00016 #include <linux/kernel.h>
00017 #include <linux/module.h>
00018 #include <linux/sched.h>
00019 #include <linux/wait.h>
00020 #include <asm/uaccess.h>
00021 #include <asm/io.h>
00022 #include <linux/slab.h>
00023 #include <linux/types.h>
00024 #include <linux/errno.h>
00025 
00026 
00027 #include <ipmux_interrupt.h>
00028 #include <opl_cpuif.h>
00032 /*--------------------------Macro definition------------------------- */
00033 #define OPL_HOST_MAJOR  130
00034 #define OPL_HOST_NAME   "opl_cpuif"
00035 
00036 #define IPMUX_DMA_NUMS  4
00037 #define OPL_DMA_VAL_MAX 2048
00038 
00039 
00045 /*--------------------------type definition------------------------- */
00046 
00047 
00048 
00049 
00055 /*-----------------global varible/function declaration--------------- */
00056 extern void ipmux_irq_enable(unsigned int irq);
00057 extern void ipmux_irq_disable(unsigned int irq);
00058 
00064 /*-------------------local  function declaration---------------------- */
00065 
00066 
00067 
00068 
00069 
00076 /*--------------local  variable declaration and definition------------- */
00077 static int opl_host_open(struct inode *inode, struct file *filp);         
00078 static ssize_t opl_host_read(struct file *filp, char  *buffer, size_t length, loff_t *offset);
00079 static ssize_t opl_host_write(struct file *filp, const char *buffer, size_t length, loff_t *offset);
00080 static int opl_host_release(struct inode *inode, struct file *filp);
00081 static int opl_host_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,u32 arg);
00082 
00083 static void host_dma0_isr(int irq,void *dev_id,struct pt_regs *regs);
00084 
00085 static u32 tx_phys_addr[IPMUX_DMA_NUMS]={0};
00086 static u32 rx_phys_addr[IPMUX_DMA_NUMS]={0};
00087 
00088 static char *dma0_rx_buf=NULL;
00089 static char *dma0_tx_buf=NULL;
00090 
00091 static u32 order = 0;
00092 static u32 opl_host_is_open = 0;
00093 static u32 opl_host_open_count = 0;
00094 static u32 opl_host_dma0_irq_event = 0;
00095 static wait_queue_head_t opl_host_dma0_waitq;
00096 struct file_operations opl_host_fops = {
00097   .open = opl_host_open,
00098   .read = opl_host_read,
00099   .write = opl_host_write,
00100   .release = opl_host_release,
00101   .ioctl = opl_host_ioctl,
00102 };
00103 
00104 
00111 /*------------------global variable and function exported-------------- */
00112 
00113 
00121 /*----------------------local  function definition--------------------- */
00122 
00134 static void host_dma0_isr(int irq,void *dev_id,struct pt_regs *regs)
00135 {
00136   if(test_and_set_bit(0,&opl_host_dma0_irq_event)){
00137     /* TBD: add some debug message here */
00138   }
00139   wake_up_interruptible(&opl_host_dma0_waitq);
00140 }
00141 
00142 
00143 static int opl_host_open(struct inode *inode,struct file *filp)
00144 {
00145   if(test_and_set_bit(0,&opl_host_is_open)){
00146     printk(KERN_DEBUG "the device is opened\n"); 
00147   }
00148   opl_host_open_count ++;
00149   MOD_INC_USE_COUNT;
00150   return 0;
00151 }
00152 
00153 static int opl_host_release(struct inode *inode,struct file *filp)
00154 {
00155   opl_host_open_count --;
00156   if(!opl_host_open_count)
00157     clear_bit(0,&opl_host_is_open);
00158   
00159   MOD_DEC_USE_COUNT;
00160   return 0;
00161 }
00162 
00163 static ssize_t opl_host_read(struct file *filp, char  *buffer, size_t length, loff_t *offset)
00164 {
00165   return 0;
00166 }
00167 
00168 static ssize_t opl_host_write(struct file *filp,const char *buf,size_t length,loff_t *offset)
00169 {
00170   return 0;
00171 }
00172 
00194 static int opl_host_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,u32 arg)
00195 {
00196   int status = 0;
00197   if(!test_bit(0,&opl_host_is_open)){
00198     return -ENODEV;
00199   }
00200   switch(cmd){
00201   case GET_IPMUX_DMA_TX_PHYS_ADDR:
00202     {
00203       int dmas= 0;
00204       dma_request_phys_addr_t *req = (dma_request_phys_addr_t *)arg;
00205       if(copy_from_user(&dmas,&req->dmas,4)){
00206       }
00207       if(tx_phys_addr[dmas]){
00208         if(copy_to_user(&req->phys_addr,&tx_phys_addr[dmas],4)){
00209         }
00210       }else{
00211         /* for others dma,not for dma0. */
00212       }
00213     }
00214     break;
00215   case GET_IPMUX_DMA_RX_PHYS_ADDR:
00216     {
00217       int dmas= 0;
00218       dma_request_phys_addr_t *req = (dma_request_phys_addr_t *)arg;
00219       if(copy_from_user(&dmas,&req->dmas,4)){
00220       }
00221       if(rx_phys_addr[dmas]){
00222         if(copy_to_user(&req->phys_addr,&rx_phys_addr[dmas],4)){
00223         }
00224       }else{
00225         /* for others dma,not for dma0. */
00226       }
00227     }
00228     break;
00229   case SET_IPMUX_DMA_TX_BUF_DATA:
00230     {
00231       dma_request_data_t req;
00232       if(copy_from_user(&req,(char *)arg,sizeof(dma_request_data_t))){
00233       }
00234       int dmas = req.dmas;
00235       int bd = req.bd;
00236       int len = req.len;
00237       if(copy_from_user((char *)(tx_phys_addr[dmas]+bd*OPL_DMA_VAL_MAX),req.buf,len)){
00238       }      
00239     }
00240     break;
00241   case GET_IPMUX_DMA_RX_BUF_DATA:
00242     {
00243       dma_request_data_t req;
00244       if(copy_from_user(&req,(char *)arg,sizeof(dma_request_data_t))){
00245       }
00246       int dmas = req.dmas;
00247       int bd = req.bd;
00248       int len = req.len;
00249       if(dmas<2){
00250         if(copy_to_user(((dma_request_data_t *)arg)->buf,
00251                         (char *)(rx_phys_addr[dmas]+bd*OPL_DMA_VAL_MAX),len)){
00252         }
00253       }
00254     }
00255     break;
00256   case ENABLE_IPMUX_HOST_DMA0_INTERRUPT:
00257     {
00258       ipmux_irq_enable(OPL_HOSTDMA0_IRQ);
00259     }
00260     break;
00261   case DISABLE_IPMUX_HOST_DMA0_INTERRUPT:
00262     {
00263       ipmux_irq_disable(OPL_HOSTDMA0_IRQ);
00264     }
00265     break;
00266   case WAIT_FOR_IPMUX_HOST_DMA0_INTERRUPT:
00267     {
00268       wait_event_interruptible(opl_host_dma0_waitq,opl_host_dma0_irq_event);
00269       if(!test_and_clear_bit(0,&opl_host_dma0_irq_event)){
00270         printk(KERN_ALERT "clear opl_host_dma0_irq_event failed \n");
00271         return -1;
00272       }
00273     }
00274     break;
00275   default:
00276     break;
00277   }
00278   return status;
00279 }
00280 
00289 static int __init opl_host_dma_init(void)
00290 {
00291   int ret = 0;
00292   int count = 0;
00293   int size = 2*64*OPL_DMA_VAL_MAX;
00294 
00295   ret = register_chrdev(OPL_HOST_MAJOR,OPL_HOST_NAME,&opl_host_fops);
00296   if(ret < 0){
00297     /* add debug Message TBD */
00298     return -1;
00299   }
00300 
00301   for (count = PAGE_SIZE, order = 0; count < size; order++, count <<= 1)
00302     ;
00303   dma0_rx_buf =(char*) __get_free_pages(GFP_KERNEL| GFP_DMA, order);
00304   if(!dma0_rx_buf){
00305     goto fail1;
00306   }
00307   memset(dma0_rx_buf,0,size);
00308   dma0_tx_buf = &dma0_rx_buf[64*OPL_DMA_VAL_MAX];
00309   rx_phys_addr[0] = (u32)dma0_rx_buf|0xa0000000; /* for mips uncacheable memory. */
00310   tx_phys_addr[0] = (u32)dma0_tx_buf|0xa0000000;
00311 
00312   init_waitqueue_head(&opl_host_dma0_waitq);
00313   ret = request_irq(OPL_HOSTDMA0_IRQ,host_dma0_isr,0,"IPMux dma0",NULL);
00314   if(ret){
00315     /* add error message */
00316     goto fail2;
00317   }
00318   return 0;
00319  fail1:
00320   ret = unregister_chrdev(OPL_HOST_MAJOR,OPL_HOST_NAME);
00321  fail2:
00322   free_pages((u32)dma0_rx_buf,order);
00323   return -1;
00324 }
00325 
00333 static void __exit opl_host_dma_exit(void)
00334 {
00335   int ret = 0;
00336    
00337   free_irq(OPL_HOSTDMA0_IRQ,NULL);
00338   free_pages((u32)dma0_rx_buf,order);
00339   ret = unregister_chrdev(OPL_HOST_MAJOR,OPL_HOST_NAME);
00340   if(ret<0){
00341     /* add debug Message TBD */
00342   }
00343 }
00344 
00345 module_init(opl_host_dma_init);
00346 module_exit(opl_host_dma_exit);
00347 MODULE_LICENSE("GPL2");
00348 MODULE_AUTHOR("opulan Inc");
00349 MODULE_DESCRIPTION("opulan IPMUX-e switch chip driver module");
00350 

Generated at Mon Jul 30 16:43:48 2007 for IPMUX1IPMUX2IPMUX3 by  doxygen 1.3.9.1