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

📄 mmc_core.c

📁 pxa270下的sd卡驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
void mmc_unregister_slot_driver( struct mmc_slot_driver *sdrive ){	int i;	DEBUG(2,"\n");	for ( i = 0 ; i < g_mmc_dev.num_slots ; i++ )		mmc_eject(i);	if ( sdrive == g_mmc_dev.sdrive ) {		g_mmc_dev.sdrive->cleanup();		g_mmc_dev.sdrive = NULL;	}}EXPORT_SYMBOL(mmc_register_slot_driver);EXPORT_SYMBOL(mmc_unregister_slot_driver);/******************************************************************/static struct pm_dev *mmc_pm_dev;static int mmc_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data){	int i;	DEBUG(0,": pm callback %d\n", req );	switch (req) {	case PM_SUSPEND: /* Enter D1-D3 */		g_mmc_dev.suspended = 1;                break;	case PM_RESUME:  /* Enter D0 */		if ( g_mmc_dev.suspended ) {			g_mmc_dev.suspended = 0;			g_mmc_dev.state = 0;     // Clear the old state			for ( i = 0 ; i < g_mmc_dev.num_slots ; i++ ) {				mmc_eject(i);				if ( !g_mmc_dev.sdrive->is_empty(i) )					mmc_insert(i);			}		}		break;        }        return 0;}#ifdef CONFIG_CEE#include <linux/device.h>static int mmc_suspend(struct device *dev, u32 state, u32 level);static int mmc_resume(struct device *dev, u32 level);static struct device_driver mmc_driver_ldm = {	name:          "mmc",	devclass:      NULL,	probe:         NULL,	suspend:       mmc_suspend,	resume:        mmc_resume,	scale:         NULL,	remove:        NULL,};static struct device mmc_device_ldm = {	name:         "MMC",	bus_id:       "mmc",	driver:       NULL,	power_state:  DPM_POWER_ON,};static voidmmc_ldm_register(void){#ifdef CONFIG_ARCH_MAINSTONE	extern void pxaopb_driver_register(struct device_driver *driver);	extern void pxaopb_device_register(struct device *device);		pxaopb_driver_register(&mmc_driver_ldm);	pxaopb_device_register(&mmc_device_ldm);#endif#ifdef CONFIG_ARCH_OMAP   extern void mpu_public_driver_register(struct device_driver *driver);   extern void mpu_public_device_register(struct device *device);   mpu_public_driver_register(&mmc_driver_ldm);   mpu_public_device_register(&mmc_device_ldm);#endif#ifdef CONFIG_ARCH_MX2ADS	extern void mx21_ldm_device_register(struct device *device);	extern void mx21_ldm_driver_register(struct device_driver *driver);	mx21_ldm_driver_register(&mmc_driver_ldm);	mx21_ldm_device_register(&mmc_device_ldm);#endif}static voidmmc_ldm_unregister(void){#ifdef CONFIG_ARCH_MAINSTONE	extern void pxaopb_driver_unregister(struct device_driver *driver);	extern void pxaopb_device_unregister(struct device *device);		pxaopb_device_unregister(&mmc_device_ldm);	pxaopb_driver_unregister(&mmc_driver_ldm);#endif#ifdef CONFIG_ARCH_OMAP   extern void mpu_public_driver_unregister(struct device_driver *driver);   extern void mpu_public_device_unregister(struct device *device);   mpu_public_driver_unregister(&mmc_driver_ldm);   mpu_public_device_unregister(&mmc_device_ldm);#endif#ifdef CONFIG_ARCH_MX2ADS	extern void mx21_ldm_device_unregister(struct device *device);	extern void mx21_ldm_driver_unregister(struct device_driver *driver);	mx21_ldm_device_unregister(&mmc_device_ldm);	mx21_ldm_driver_unregister(&mmc_driver_ldm);#endif}static intmmc_resume(struct device *dev, u32 level){	int i;	switch (level) {	case RESUME_RESTORE_STATE:	case RESUME_ENABLE:	case RESUME_POWER_ON:		/* Enter D0 */		if ( g_mmc_dev.suspended ) {			g_mmc_dev.suspended = 0;			g_mmc_dev.state = 0;     // Clear the old state			for ( i = 0 ; i < g_mmc_dev.num_slots ; i++ ) {				mmc_eject(i);				if ( !g_mmc_dev.sdrive->is_empty(i) )					mmc_insert(i);			}		}		break;	}	return 0;}static intmmc_suspend(struct device *dev, u32 state, u32 level){	switch (level) {	case SUSPEND_NOTIFY:	case SUSPEND_SAVE_STATE:	case SUSPEND_DISABLE:	case SUSPEND_POWER_DOWN:		/* Enter D1-D3 */		g_mmc_dev.suspended = 1;		break;	}	return 0;}#endif /* CONFIG_CEE *//****************************************************************** * TODO: These would be better handled by driverfs * For the moment, we'll just eject and insert everything ******************************************************************/int mmc_do_eject(ctl_table *ctl, int write, struct file * filp, void *buffer, size_t *lenp){	mmc_eject(0);	return 0;}int mmc_do_insert(ctl_table *ctl, int write, struct file * filp, void *buffer, size_t *lenp){	mmc_insert(0);	return 0;}static struct ctl_table mmc_sysctl_table[] ={	{ 1, "debug", &g_mmc_debug, sizeof(int), 0666, NULL, &proc_dointvec },	{ 2, "eject", NULL, 0, 0600, NULL, &mmc_do_eject },	{ 3, "insert", NULL, 0, 0600, NULL, &mmc_do_insert },	{0}};static struct ctl_table mmc_dir_table[] ={	{BUS_MMC, "mmc", NULL, 0, 0555, mmc_sysctl_table},	{0}};static struct ctl_table bus_dir_table[] = {	{CTL_BUS, "bus", NULL, 0, 0555, mmc_dir_table},        {0}};static struct ctl_table_header *mmc_sysctl_header;/* Wangzheng */static int mmc_proc_read_device(char *page, char **start, off_t off, int count, int *eof, void *data){	struct mmc_dev *dev = (struct mmc_dev *)data;        char *p = page;        int len = 0;	int i;	if (!dev || !dev->sdrive)		return 0;	for ( i = 0 ; i < dev->num_slots ; i++ ) {		struct mmc_slot *slot = &dev->slot[i];		p += sprintf(p, "Slot #%d\n", i);		p += sprintf(p, "  State %s (%d)\n", card_state_to_string(slot->state), slot->state);		if ( slot->state != CARD_STATE_EMPTY ) {			if(!slot->sd) {			p += sprintf(p, "  Media %s\n", (slot->media_driver ? slot->media_driver->name : "unknown"));			p += sprintf(p, "  CID mid=%d\n", slot->cid.cid_mmc.mid);			p += sprintf(p, "      oid=%d\n", slot->cid.cid_mmc.oid);			p += sprintf(p, "      pnm=%s\n", slot->cid.cid_mmc.pnm);			p += sprintf(p, "      prv=%d.%d\n", slot->cid.cid_mmc.prv>>4, slot->cid.cid_mmc.prv&0xf);			p += sprintf(p, "      psn=0x%08x\n", slot->cid.cid_mmc.psn);			p += sprintf(p, "      mdt=%d/%d\n", slot->cid.cid_mmc.mdt&0xf, (slot->cid.cid_mmc.mdt>>4)+2000);			p += sprintf(p, "  CSD csd_structure=%d\n", slot->csd.csd_mmc.csd_structure);			p += sprintf(p, "      spec_vers=%d\n", slot->csd.csd_mmc.spec_vers);			p += sprintf(p, "      taac=0x%02x\n", slot->csd.csd_mmc.taac);			p += sprintf(p, "      nsac=0x%02x\n", slot->csd.csd_mmc.nsac);			p += sprintf(p, "      tran_speed=0x%02x\n", slot->csd.csd_mmc.tran_speed);			p += sprintf(p, "      ccc=0x%04x\n", slot->csd.csd_mmc.ccc);			p += sprintf(p, "      read_bl_len=%d\n", slot->csd.csd_mmc.read_bl_len);			p += sprintf(p, "      read_bl_partial=%d\n", slot->csd.csd_mmc.read_bl_partial);			p += sprintf(p, "      write_blk_misalign=%d\n", slot->csd.csd_mmc.write_blk_misalign);			p += sprintf(p, "      read_blk_misalign=%d\n", slot->csd.csd_mmc.read_blk_misalign);			p += sprintf(p, "      dsr_imp=%d\n", slot->csd.csd_mmc.dsr_imp);			p += sprintf(p, "      c_size=%d\n", slot->csd.csd_mmc.c_size);			p += sprintf(p, "      vdd_r_curr_min=%d\n", slot->csd.csd_mmc.vdd_r_curr_min);			p += sprintf(p, "      vdd_r_curr_max=%d\n", slot->csd.csd_mmc.vdd_r_curr_max);			p += sprintf(p, "      vdd_w_curr_min=%d\n", slot->csd.csd_mmc.vdd_w_curr_min);			p += sprintf(p, "      vdd_w_curr_max=%d\n", slot->csd.csd_mmc.vdd_w_curr_max);			p += sprintf(p, "      c_size_mult=%d\n", slot->csd.csd_mmc.c_size_mult);			p += sprintf(p, "      wp_grp_size=%d\n", slot->csd.csd_mmc.wp_grp_size);			p += sprintf(p, "      wp_grp_enable=%d\n", slot->csd.csd_mmc.wp_grp_enable);			p += sprintf(p, "      default_ecc=%d\n", slot->csd.csd_mmc.default_ecc);			p += sprintf(p, "      r2w_factor=%d\n", slot->csd.csd_mmc.r2w_factor);			p += sprintf(p, "      write_bl_len=%d\n", slot->csd.csd_mmc.write_bl_len);			p += sprintf(p, "      write_bl_partial=%d\n", slot->csd.csd_mmc.write_bl_partial);			p += sprintf(p, "      file_format_grp=%d\n", slot->csd.csd_mmc.file_format_grp);			p += sprintf(p, "      copy=%d\n", slot->csd.csd_mmc.copy);			p += sprintf(p, "      perm_write_protect=%d\n", slot->csd.csd_mmc.perm_write_protect);			p += sprintf(p, "      tmp_write_protect=%d\n", slot->csd.csd_mmc.tmp_write_protect);			p += sprintf(p, "      file_format=%d\n", slot->csd.csd_mmc.file_format);			p += sprintf(p, "      ecc=%d\n", slot->csd.csd_mmc.ecc);			switch (slot->csd.csd_mmc.csd_structure) {			case CSD_STRUCT_VER_1_0:			case CSD_STRUCT_VER_1_1:				p += sprintf(p, "      sector_size=%d\n", slot->csd.csd_mmc.erase.v22.sector_size);				p += sprintf(p, "      erase_grp_size=%d\n", slot->csd.csd_mmc.erase.v22.erase_grp_size);				break;			case CSD_STRUCT_VER_1_2:			default:				p += sprintf(p, "      erase_grp_size=%d\n", slot->csd.csd_mmc.erase.v31.erase_grp_size);				p += sprintf(p, "      erase_grp_mult=%d\n", slot->csd.csd_mmc.erase.v31.erase_grp_mult);				break;			}			}			else {			p += sprintf(p, "  Media %s\n", (slot->media_driver ? slot->media_driver->name : "unknown"));			p += sprintf(p, "  CID mid=%d\n", slot->cid.cid_sd.mid);			p += sprintf(p, "      oid=%d\n", slot->cid.cid_sd.oid);			p += sprintf(p, "      pnm=%s\n", slot->cid.cid_sd.pnm);			p += sprintf(p, "      prv=%d.%d\n", slot->cid.cid_sd.prv>>4, slot->cid.cid_sd.prv&0xf);			p += sprintf(p, "      psn=0x%08x\n", slot->cid.cid_sd.psn);			p += sprintf(p, "      mdt=%d/%d\n", slot->cid.cid_sd.mdt>>4, (slot->cid.cid_sd.mdt&0xf)+2000);			p += sprintf(p, "  CSD csd_structure=%d\n", slot->csd.csd_sd.csd_structure);			p += sprintf(p, "      spec_vers=%d\n", slot->csd.csd_sd.spec_vers);			p += sprintf(p, "      taac=0x%02x\n", slot->csd.csd_sd.taac);			p += sprintf(p, "      nsac=0x%02x\n", slot->csd.csd_sd.nsac);			p += sprintf(p, "      tran_speed=0x%02x\n", slot->csd.csd_sd.tran_speed);			p += sprintf(p, "      ccc=0x%04x\n", slot->csd.csd_sd.ccc);			p += sprintf(p, "      read_bl_len=%d\n", slot->csd.csd_sd.read_bl_len);			p += sprintf(p, "      read_bl_partial=%d\n", slot->csd.csd_sd.read_bl_partial);			p += sprintf(p, "      write_blk_misalign=%d\n", slot->csd.csd_sd.write_blk_misalign);			p += sprintf(p, "      read_blk_misalign=%d\n", slot->csd.csd_sd.read_blk_misalign);			p += sprintf(p, "      dsr_imp=%d\n", slot->csd.csd_sd.dsr_imp);			p += sprintf(p, "      c_size=%d\n", slot->csd.csd_sd.c_size);			p += sprintf(p, "      vdd_r_curr_min=%d\n", slot->csd.csd_sd.vdd_r_curr_min);			p += sprintf(p, "      vdd_r_curr_max=%d\n", slot->csd.csd_sd.vdd_r_curr_max);			p += sprintf(p, "      vdd_w_curr_min=%d\n", slot->csd.csd_sd.vdd_w_curr_min);			p += sprintf(p, "      vdd_w_curr_max=%d\n", slot->csd.csd_sd.vdd_w_curr_max);			p += sprintf(p, "      c_size_mult=%d\n", slot->csd.csd_sd.c_size_mult);			p += sprintf(p, "      erase_blk_enable=%d\n", slot->csd.csd_sd.erase_blk_enable);			p += sprintf(p, "      erase_sector_size=%d\n", slot->csd.csd_sd.erase_sector_size);			p += sprintf(p, "      wp_grp_size=%d\n", slot->csd.csd_sd.wp_grp_size);			p += sprintf(p, "      wp_grp_enable=%d\n", slot->csd.csd_sd.wp_grp_enable);			p += sprintf(p, "      r2w_factor=%d\n", slot->csd.csd_sd.r2w_factor);			p += sprintf(p, "      write_bl_len=%d\n", slot->csd.csd_sd.write_bl_len);			p += sprintf(p, "      write_bl_partial=%d\n", slot->csd.csd_sd.write_bl_partial);			p += sprintf(p, "      file_format_grp=%d\n", slot->csd.csd_sd.file_format_grp);			p += sprintf(p, "      copy=%d\n", slot->csd.csd_sd.copy);			p += sprintf(p, "      perm_write_protect=%d\n", slot->csd.csd_sd.perm_write_protect);			p += sprintf(p, "      tmp_write_protect=%d\n", slot->csd.csd_sd.tmp_write_protect);			p += sprintf(p, "      file_format=%d\n", slot->csd.csd_sd.file_format);						}		}	}        len = (p - page) - off;	*start = page + off;        return len;}/******************************************************************/void mmc_protocol_single_card( struct mmc_dev *dev, int state_flags );extern struct mmc_media_module media_module;static int __init mmc_init(void) {	DEBUG(1, "Init MMC subsystem\n");		mmc_sysctl_header = register_sysctl_table(bus_dir_table, 0 );	tasklet_init(&g_mmc_dev.task,mmc_tasklet_action,(unsigned long)&g_mmc_dev);	g_mmc_dev.protocol = mmc_protocol_single_card;	proc_mmc_dir = proc_mkdir("mmc", proc_bus);	if ( proc_mmc_dir )		create_proc_read_entry("device", 0, proc_mmc_dir, mmc_proc_read_device, &g_mmc_dev);	mmc_pm_dev = pm_register(PM_UNKNOWN_DEV, PM_SYS_UNKNOWN, mmc_pm_callback);	#ifdef CONFIG_CEE	mmc_ldm_register();#endif /* CONFIG_CEE */ 	media_module.init();	return 0;}static void __exit mmc_exit(void){	DEBUG(1,"\n");	media_module.cleanup();	unregister_sysctl_table(mmc_sysctl_header);	tasklet_kill(&g_mmc_dev.task);	if ( proc_mmc_dir ) {		remove_proc_entry("device", proc_mmc_dir);		remove_proc_entry("mmc", proc_bus);	}	pm_unregister(mmc_pm_dev);	#ifdef CONFIG_CEE	mmc_ldm_unregister();#endif /* CONFIG_CEE */ }module_init(mmc_init);module_exit(mmc_exit);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -