static int __init gdma_init(void)
{
    int ret;

    GDMA_MSG("GDMA initialize\n");
	
    GDMA_MSG("Register the GDMA device\n");
	if(platform_device_register(&gdma_device))
	{
        GDMA_ERR("failed to register gdma device\n");
        ret = -ENODEV;
        return ret;
	}

    GDMA_MSG("Register the GDMA driver\n");    
    if(platform_driver_register(&gdma_driver))
    {
        GDMA_ERR("failed to register gdma driver\n");
        platform_device_unregister(&gdma_device);
        ret = -ENODEV;
        return ret;
    }

    return 0;
}
static int gdma_remove(struct platform_device *pdev)
{
	GDMA_MSG("GDMA remove\n");
	//unregister_chrdev(GDMA_MAJOR, GDMA_DEVNAME);
//#ifdef GDMA_IRQ
//	free_irq(MT6575_GDMA_IRQ_ID, NULL);
//#endif
	GDMA_MSG("Done\n");
	return 0;
}
static int gdma_probe(struct platform_device *pdev)
{
#ifdef GDMA_DEV
	int ret;
    struct class_device *class_dev = NULL;
    
    GDMA_MSG("-------------gdma driver probe-------\n");
	ret = alloc_chrdev_region(&gdma_devno, 0, 1, GDMA_DEVNAME);

	if(ret)
	{
	    GDMA_ERR("Error: Can't Get Major number for GDMA Device\n");
	}
	else
	{
	    GDMA_MSG("Get GDMA Device Major number (%d)\n", gdma_devno);
    }

	gdma_cdev = cdev_alloc();
    gdma_cdev->owner = THIS_MODULE;
	gdma_cdev->ops = &gdma_fops;

	ret = cdev_add(gdma_cdev, gdma_devno, 1);

    gdma_class = class_create(THIS_MODULE, GDMA_DEVNAME);
    class_dev = (struct class_device *)device_create(gdma_class, NULL, gdma_devno, NULL, GDMA_DEVNAME);
#else

    proc_create("mtk_gdma", 0, NULL, &gdma_fops);

#endif
    spin_lock_init(&gdma_ctl_lock);

    // initial GDMA, register ISR
    ctr_status = 0;
    _gdma_ctr_int_status = 0;

//#ifdef GDMA_IRQ
//    init_waitqueue_head(&gdma_wait_queue);  
//    
//
//    enable_irq(MT6575_GDMA_IRQ_ID);
//    if(request_irq(MT6575_GDMA_IRQ_ID, gdma_drv_isr, IRQF_TRIGGER_LOW, "gdma_driver" , NULL))
//    {
//        GDMA_ERR("GDMA Driver request irq failed\n");
//    }
//#endif
	GDMA_MSG("GDMA Probe Done\n");

#ifdef GDMA_DEV
	NOT_REFERENCED(class_dev);
#endif
	return 0;
}
static void __exit gdma_exit(void)
{
    cdev_del(gdma_cdev);
    unregister_chrdev_region(gdma_devno, 1);
	  //GDMA_MSG("Unregistering driver\n");
    platform_driver_unregister(&gdma_driver);
	  platform_device_unregister(&gdma_device);
	
	  device_destroy(gdma_class, gdma_devno);
	  class_destroy(gdma_class);
	  
	  GDMA_MSG("Done\n");
}
static void __exit gdma_exit(void)
{
#ifdef GDMA_DEV
    cdev_del(gdma_cdev);
    unregister_chrdev_region(gdma_devno, 1);
    //GDMA_MSG("Unregistering driver\n");

    device_destroy(gdma_class, gdma_devno);
    class_destroy(gdma_class);
#else
    remove_proc_entry("mtk_gdma", NULL);
#endif
    platform_driver_unregister(&gdma_driver);
    platform_device_unregister(&gdma_device);
  
    GDMA_MSG("Done\n");
}
static void gdma_shutdown(struct platform_device *pdev)
{
	GDMA_MSG("GDMA shutdown\n");
	/* Nothing yet */
}
static ssize_t gdma_read(struct file *file, char __user *data, size_t len, loff_t *ppos)
{
    GDMA_MSG("gdma driver read\n");
    return 0;
}
static int gdma_ctl_ioctl( unsigned int cmd, unsigned long arg, struct file *file)
//static int GDMA_Ioctl(struct inode * a_pstInode, struct file * file, unsigned int cmd, unsigned long arg)
{
#ifdef GDMA_INC_FPGA    
    unsigned int timeout = 0x4FFFFF;
    unsigned int idx;
    unsigned int addr;
#endif    
    //GDMA_DRV_FMT_IN fmtParam;
    GDMA_DRV_CTL_IN ctlParam;
    //CONFIG_DRV_CDP_IN ispParam;

    unsigned int*       pStatus;
    //unsigned int        chksum;
    //unsigned char       whichBank;

    
    pStatus = (unsigned int*)file->private_data;

    if (NULL == pStatus)
    {
        GDMA_MSG("Private data is null in flush operation. SOME THING WRONG??\n");
        return -EFAULT;
    }    
    
    switch(cmd)
    {     
      case GDMA_IOCTL_INIT:
            GDMA_MSG("GDMA Initial and Lock\n");
            if(gdma_drv_init() == 0)
            {
                *pStatus = GDMA_CTL_PROCESS;
            }         
         
         break; 

      case GDMA_IOCTL_RESET:  /* OT:OK */
          GDMA_MSG("GDMA Reset\n");
          gdma_drv_reset();
          break;       
          
      case GDMA_IOCTL_DEINIT:
          GDMA_MSG("GDMA Deinit Hardware\n");
          // copy input parameters
          if(*pStatus != GDMA_CTL_PROCESS)
          {
              printk("Permission Denied! This process can not access GDMA_CTL");
              return -EFAULT;
          }

          if(ctr_status == 0)
          {
              printk("GDMA_CTL status is available, HOW COULD THIS HAPPEN ??");
              *pStatus = 0;
              return -EFAULT;
          }
          gdma_drv_deinit();
          *pStatus = 0;   
          break;          
          
      case GDMA_IOCTL_CONFIG_CTL:
        
         
          GDMA_MSG("GDMA Configure Hardware\n");
          if(*pStatus != GDMA_CTL_PROCESS)
          {
              GDMA_MSG("Permission Denied! This process can not access GDMA\n");
              return -EFAULT;
          }
          if(ctr_status == 0)
          {
              GDMA_MSG("GDMA is unlocked!!");
              *pStatus = 0;
              return -EFAULT;
          }         
          if (copy_from_user(&ctlParam, (void*)arg, sizeof(GDMA_DRV_CTL_IN)))
          {
              printk("Copy from user failed\n");
              return -EFAULT;
          }
          #ifdef GDMA_INC_FPGA          
            if(ctlParam.isSrcGray){
              gISP_yuv_en = 4; //disable cb/cr DMA
            }
          #endif          
           
          gdma_config_ctl(&ctlParam);
        break;   

      
      case GDMA_IOCTL_RW_REG:
          gdma_rw_reg();
        break;
        
      case GDMA_IOCTL_DUMP_REG:
          GDMA_MSG("GDMA Dump Hardware Reg\n");
          gdma_dump_reg();
        break;

#ifdef GDMA_INC_FPGA        
{
//      case GDMA_IOCTL_INIT:{
//      
//          addr = CAM_REG_BASE + 0x0000;
//          *(volatile unsigned int *)(addr) = 0;
//          
//          if (gdma_reset_isp() < 0)
//              return -EFAULT;        
//        }break;
//        
//      case GDMA_IOCTL_RESET:{
//      
//          if (gdma_reset_isp() < 0)
//              return -EFAULT;
//        }break;
//
//      case GDMA_IOCTL_CONFIG_ISP:{
//          printk("GDMA ISP Config\n");
//          if (copy_from_user(&ispParam, (void*)arg, sizeof(CONFIG_DRV_CDP_IN)))
//          {
//              printk("Copy from user failed\n");
//              return -EFAULT;
//          }
//          gStartISP = ispParam.startISP;     
//          gGDMALink = ispParam.linkGDMA;
//          gFMT_en   = ispParam.fmtEn;
//          gISP_TDRI_en = ispParam.isp_TDRIen ;
//          gISP_yuv_en = 7; //default enable YUV DMA
//      
//          if (gStartISP){
//              if(gISP_TDRI_en ){
//                 if( !ispParam.isp_TDRI_resume)
//                   gdma_isp_setup_tdri();
//              }else{
//                 gdma_isp_setup();  
//              }
//          }
//          
//          printk("ISP modify: %d\n", ispParam.numModify);
//          for (idx = 0; idx < ispParam.numModify; idx++)
//          {
//              printk("%08x %08x\n", ispParam.modifyOffset[idx], ispParam.modifyValue[idx]);
//              wait_pr();
//      
//              write_reg(ispParam.modifyOffset[idx], ispParam.modifyValue[idx]);
//          }
//      }break;
//        
//      
//      case GDMA_IOCTL_START :{
//               
//          printk(" Link GDMA: %d, Trigger ISP: %d, FMT %d, Enable GDMA: %d, YUV_DMA %d!!\n", gGDMALink, gStartISP, gFMT_en ,ispParam.gdmaEn, gISP_yuv_en);
//          gdma_start(gGDMALink, gStartISP, gFMT_en, gISP_yuv_en);
//        }break;      
//
//      case GDMA_IOCTL_CONFIG_FMT:{  
//          printk("GDMA FMT Config\n");
//          if (copy_from_user(&fmtParam, (void*)arg, sizeof(GDMA_DRV_FMT_IN)))
//          {
//              printk("Copy from user failed\n");
//              return -EFAULT;
//          }
//          gdma_config_fmt(fmtParam);
//      }break;
}      
#endif 
        
      default:
          printk("GDMA NO THIS IOCTL COMMAND, %d!!\n", cmd);
        break;
    }
    return 0;
}
void gdma_drv_power_off(void)
{  
    GDMA_MSG("GDMA Power Off\n");
}
void gdma_drv_power_on(void)
{  
    GDMA_MSG("GDMA Power On\n");
}