⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmc_main.c.bak

📁 MMC 0.4.0驱动 龙珠 MOTO板子
💻 BAK
📖 第 1 页 / 共 5 页
字号:
	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 + -