📄 mmc_main.c.bak
字号:
ret = request_irq(MMCSD_SOCKET1_INT, mmcsd_socket1_irq_handler, SA_INTERRUPT|SA_SHIRQ, "mmc", "mmc");#endif*/ if(ret) { TRACE("request irq error"); goto fail_init; } // tasklet_init(&mmc_tasklet, mmc_tasklet_action,(unsigned long)0); create_proc_read_entry ("mmc", 0, 0, mmcsd_read_proc, NULL); _mmcsd_socket1_irq_set(); return 0; /****************************************************** * Enable SDHC module ******************************************************/fail_init: read_ahead[g_mmcsd_major] = 0; if (g_mmcsd_devices) { kfree(g_mmcsd_devices); } free_irq(MMCSD_IRQ,"mmc");#ifdef CONFIG_ARCH_MX2ADS free_irq(MMCSD2_IRQ,"mmc1"); free_irq(MMCSD_SOCKET1_INT,"mmc"); devfs_unregister(devfs_handle1);#endif devfs_unregister_blkdev(g_mmcsd_major, "mmc"); devfs_unregister(devfs_handle); return ret;}/** *@brief mmc cleanup function * * Function Name: mmcsd_cleanup * *@return None * * Description: This is the cleanup routine for the driver. And this function \n * will be called while the module being removed. In this function, it will \n * cleanup all the registered entries * * Modification History: * **/#ifdef MODULEvoid cleanup_module(void)#elseint __exit mmcsd_cleanup(void)#endif{ pm_unregister_all(handle_pm_event); apmc_unregister(g_Mmc_apmc);// tasklet_kill(&mmc_tasklet); read_ahead[g_mmcsd_major] = 0; if (g_mmcsd_devices) { kfree(g_mmcsd_devices); } free_irq(MMCSD_IRQ,"mmc");#ifdef CONFIG_ARCH_MX2ADS free_irq(MMCSD2_IRQ,"mmc1"); _mmcsd_socket1_disable_irq(); free_irq(MMCSD_SOCKET1_INT,"mmc"); remove_proc_entry("mmc", NULL);#endif devfs_unregister_blkdev(g_mmcsd_major, "mmc"); devfs_unregister(devfs_handle);#ifdef CONFIG_ARCH_MX2ADS devfs_unregister(devfs_handle1);#endif return ;}static int mmcsd_revalidate(kdev_t dev){ return 0;}/** *@brief mmc open function * * Function Name: mmcsd_open * * * Description: This is the open routine for the driver. And this function \n * will be called while the module being opened. In this function, it will \n * @li enable sdhc clkgate * @li call _MMCSD_InitMMC to check if it is MMC card * @li check and aqquire CSD/CID register data, * @li set sector length * @li get rca, select the card * @li initialize DMA * @li get MBR information * *@param inode the pointer to the inode descripter *@param filp the pointer to the file descripter * *@return int return status * @li 0 sucessful * @li other failed * Modification History: * **/static int mmcsd_open(struct inode *inode, struct file *filp){ MMCSD_Dev *device; int num,i,ret,major; int channel=-1; TRACE("mmcsd_open is called"); /********************************************************************* * Check the device numer *********************************************************************/ num = MINOR(inode->i_rdev); major = MAJOR(inode->i_rdev); gSDWriteProtect = 0; apmc_set_level(g_Mmc_apmc,APMC_LEVEL_LOWEST); #ifdef CONFIG_ARCH_MX2ADS if(num == 0) _reg_CRM_PCCR0 |= 0x0200;//enable sdhc1 clk else if(num == 1) _reg_CRM_PCCR0 |= 0x0400;//enable sdhc2 clk #endif if(!filp) { TRACE(" called without filp"); return -EIO; } if(num > g_mmcsd_num) { return -ENODEV; } device = &g_mmcsd_devices[num]; device->port = num; /***************************************************************** * Initialize the device *****************************************************************/ spin_lock(&device->lock); down_interruptible(&(device->sema)); ret = 0; if(device->usage == 0) { /****************************************************** * Initialize Cards ******************************************************/ _MMCSD_64M_MMC_PinConfig(); _MMCSD_InitSDHC(num); ret = _MMCSD_InitMMC(num); if(ret) { FAILED("_MMC_Init error"); goto fail_malloc; } ret = _MMCSD_GetInfo(device); // Implement if(ret) { FAILED("_MMCSD_GetInfo error!"); spin_unlock(&device->lock); up(&(device->sema)); goto fail_malloc; } ret = _MMCSD_SetSectLen(device); // Implement if(ret) { FAILED(" _MMCSD_SetSectLen error!"); spin_unlock(&device->lock); up(&(device->sema)); goto fail_malloc; } device->blksize = MMCSD_MINIMUM_BLK_SIZE; blk_size[major] = kmalloc(sizeof(int), GFP_KERNEL); if (!blk_size[major]) goto fail_malloc; blk_size[major][num] = device->dev_size/1024;/* in KB */ blksize_size[major]= kmalloc(sizeof(int), GFP_KERNEL); if (!blksize_size[major]) goto fail_malloc; blksize_size[major][num] = device->blksize;/* in B*/ hardsect_size[major]=kmalloc(sizeof(int), GFP_KERNEL); if (!hardsect_size[major]) goto fail_malloc; hardsect_size[major][num] = device->blksize;/* in B*/ ret = _MMCSD_SelectDeselectCard(device->card_rca,device->port); if(ret) { FAILED("Select error"); device->card_state = MMCSD_NOTREADY; goto fail_malloc; } /*********************************************************** * Initialize DMA ***********************************************************/#ifdef CONFIG_ARCH_MX1ADS for(channel = 2; channel < 11; channel++) { if((ret = request_dma(channel, "mmc"))==0) { //TRACE("Get Channel %ld",channel); break; } } if(channel >10) goto fail_malloc; device->dma_channel = channel; request_dma_intr(channel,(void *)mmcsd_dma_isr,(void *)mmcsd_dma_err_isr);#endif#ifdef CONFIG_ARCH_MX2ADS if(num == 1) { mx_request_dma(&channel,"mmc1"); (device->dma).callback = (void *)mmcsd_dma_isr_1; } else { mx_request_dma(&channel,"mmc"); (device->dma).callback = (void *)mmcsd_dma_isr; } device->dma_channel = channel;#endif /*********************************************************** * Initialize buff_pool for write operations. **********************************************************/ device->buff_pool[0]=kmalloc(sizeof(u8)*(device->blksize)*MMCSD_MAX_MULTI_BLK, GFP_KERNEL|GFP_DMA);#ifdef MMCSD_DMA_ENDIAN_ERR device->tmp_pool[0]=kmalloc(sizeof(u8)*(device->blksize)*MMCSD_MAX_MULTI_BLK, GFP_KERNEL|GFP_DMA);#endif if(device->buff_pool[0]==NULL) { FAILED("Allocate Buffer failed"); goto fail_malloc; } for(i = 0; i< MMCSD_MAX_MULTI_BLK;i++) { device->buff_pool[i] = device->buff_pool[0]+(device->blksize)*i;#ifdef MMCSD_DMA_ENDIAN_ERR device->tmp_pool[i] = device->tmp_pool[0]+(device->blksize)*i;#endif } device->cur_sec = 0xFFFFFFFF; device->cur_num = 0; device->busy = 0; device->bit_width = 0; _MMCSD_SetClk(MMCSD_HIGH_SPEED,num); /*********************************************************** * Get MBR ***********************************************************/ ret = mmcsd_getMBR(device); if(ret) { FAILED("mmcsd_getMBR error!"); goto fail_malloc; } ret = 0; } (device->usage)++; spin_unlock(&device->lock); up(&(device->sema)); MOD_INC_USE_COUNT; gSDumounted = 1; return ret;fail_malloc: if (blk_size[major]) kfree(blk_size[major]); blk_size[major] = NULL; if (blksize_size[major]) kfree(blksize_size[major]); blksize_size[major] = NULL; if (hardsect_size[major]) kfree(hardsect_size[major]); hardsect_size[major] = NULL;#ifdef CONFIG_ARCH_MX1ADS if(device->dma_channel!= 0xFFFFFFFF) free_dma(device->dma_channel);#endif#ifdef CONFIG_ARCH_MX2ADS if(device->dma_channel!= 0xFFFFFFFF) mx_free_dma(device->dma_channel);#endif if(device->buff_pool[0]!=NULL) kfree(device->buff_pool[0]); spin_unlock(&device->lock); up(&(device->sema)); return MMCSD_ERROR;}/** *@brief mmc close function * * Function Name: mmcsd_release * * * Description: This is the release routine for the driver. And this function \n * will be called while the module being closed. In this function, it will \n * @li disable sdhc clkgate * @li deselect the card * @li free DMA channel * *@param inode the pointer to the inode descripter *@param filp the pointer to the file descripter * *@return int return status * @li 0 sucessful * @li other failed * Modification History: * **/static int mmcsd_release(struct inode *inode, struct file *filp){ MMCSD_Dev * device; int num; u32 state; MMCSD_STATUS ret; TRACE("mmcsd_release is called"); /********************************************************************* * Check the device numer *********************************************************************/ num = MINOR(inode->i_rdev); if(num > g_mmcsd_num) { return -ENODEV; } device = &g_mmcsd_devices[num]; /***************************************************************** * Initialize the device *****************************************************************/ spin_lock(&device->lock); down_interruptible(&(device->sema)); (device->usage)--; if(device->usage == 0) { fsync_dev(inode->i_rdev); _reg_CRM_PCCR0 |= 0x0200;//disable sdhc1 clk _reg_CRM_PCCR0 |= 0x0400;//disable sdhc2 clk _MMCSD_StartClk(0); _MMCSD_StartClk(1); _MMCSD_SetClk(MMCSD_HIGH_SPEED,0);#ifdef CONFIG_ARCH_MX2ADS _MMCSD_SetClk(MMCSD_HIGH_SPEED,1);#endif#ifdef MMCSD_WRITE_DMA mmcsd_dma_write_blks(device);#else mmcsd_write_blks(device);#endif state =MMCSD_TRANSFER; mmcsd_check_status(device,&state); ret = _MMCSD_SelectDeselectCard(0,device->port); if(ret) { TRACE("Select error"); device->card_state = MMCSD_NOTREADY; //device->card_type = MMCSD_NO_CARD; // g_selected_lock.device = NULL; // spin_unlock(g_selected_lock.lock); }// _MMCSD_StopClk();// Start_Stop_Clk(1); g_selected_lock[0].device = NULL; g_selected_lock[1].device = NULL; #ifdef CONFIG_ARCH_MX1ADS if(device->dma_channel!= 0xFFFFFFFF) free_dma(device->dma_channel);#endif#ifdef CONFIG_ARCH_MX2ADS if(device->dma_channel!= 0xFFFFFFFF) mx_free_dma(device->dma_channel);#endif if(device->buff_pool[0]!=NULL) kfree(device->buff_pool[0]);#ifdef MMCSD_DMA_ENDIAN_ERR if(device->buff_pool[0]!=NULL) kfree(device->buff_pool[0]);#endif } MOD_DEC_USE_COUNT; spin_unlock(&device->lock); up(&(device->sema)); _MMCSD_StopClk(0); _MMCSD_StopClk(1); _reg_CRM_PCCR0 &= ~0x0200;//disable sdhc1 clk _reg_CRM_PCCR0 &= ~0x0400;//disable sdhc2 clk//end apmc_set_level(g_Mmc_apmc,APMC_LEVEL_HIGHEST); gSDumounted = 0; return 0;}/****************************************************************************** * Function Name: mmcsd_locate_device * * Input: * q: the pointer to request structure. * * Value Returned: * NULL: no device structure found; * pointer: to MMCSD_Device structure. * * Description: * this routine will return corresponding MMCSD device structure of the * request. * * Modification History: *****************************************************************************/static MMCSD_Dev *mmcsd_locate_device(const struct request *req){ int devno; devno = DEVICE_NR(req->rq_dev); if(devno >= g_mmcsd_num) { TRACE("\nmmcsd_locate_device: devno = %d", devno); return NULL; } return(&g_mmcsd_devices[devno]);}/** *@brief mmc request handler * * Function Name: mmcsd_request_handler * * * Description:This is the request handler for read/write operations. * *@param request_queue_t the request queue the handler will process * *@return NULL * * Modification History: * **/void mmcsd_request_handler(request_queue_t * q){ MMCSD_Dev * device; struct request *req; int ret; /*********************************************************************** * Locate the device ***********************************************************************/ device = mmcsd_locate_device(blkdev_entry_next_request(&(q->queue_head))); if(!device) { TRACE(" mmcsd_locate_device error"); return ; } device->busy = 1; /********************************************************************** * process the request quueue. **********************************************************************/ while(!list_empty(&q->queue_head)) {// _reg_CRM_PCCR0 |= 0x0200;//disable sdhc1 clk// _reg_CRM_PCCR0 |= 0x0400;//disable sdhc2 clk// _MMCSD_StartClk(0);// _MMCSD_StartClk(1); _MMCSD_SetClk(MMCSD_HIGH_SPEED,0);#ifdef CONFIG_ARCH_MX2ADS _MMCSD_SetClk(MMCSD_HIGH_SPEED,1);#endif req = blkdev_entry_next_request(&(q->queue_head)); blkdev_dequeue_request(req); spin_unlock_irq(&io_request_lock); down_interruptible(&(device->sema)); do { //TRACE("New Request coming"); ret = mmcsd_data_transfer(device, req); }while(end_that_request_first(req,ret,DEVICE_NAME)); up(&(device->sema)); spin_lock_irq(&io_request_lock); end_that_request_last(req);// _MMCSD_StopClk(0);// _MMCSD_StopClk(1);// _reg_CRM_PCCR0 &= ~0x0200;//disable sdhc1 clk// _reg_CRM_PCCR0 &= ~0x0400;//disable sdhc2 clk } device->busy = 0; return ;}/** *@brief mmc data transfer function * * Function Name: mmcsd_data_transfer * * * Description:this routine will start the read/write transfer. . * *@param device: the device that the transfer will take place. *@param req: the request that will be processed. * *@return int return status * @li 1 sucessful * @li 0 failed * * Modification History:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -