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

📄 sbc8240.c

📁 基于linux-2.6.28的mtd驱动
💻 C
字号:
/* * Handle mapping of the flash memory access routines on the SBC8240 board. * * Carolyn Smith, Tektronix, Inc. * * This code is GPLed *//* * The SBC8240 has 2 flash banks. * Bank 0 is a 512 KiB AMD AM29F040B; 8 x 64 KiB sectors. * It contains the U-Boot code (7 sectors) and the environment (1 sector). * Bank 1 is 4 x 1 MiB AMD AM29LV800BT; 15 x 64 KiB sectors, 1 x 32 KiB sector, * 2 x 8 KiB sectors, 1 x 16 KiB sectors. * Both parts are JEDEC compatible. */#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <asm/io.h>#include <linux/mtd/mtd.h>#include <linux/mtd/map.h>#include <linux/mtd/cfi.h>#ifdef CONFIG_MTD_PARTITIONS#include <linux/mtd/partitions.h>#endif#define	DEBUG#ifdef	DEBUG# define debugk(fmt,args...)	printk(fmt ,##args)#else# define debugk(fmt,args...)#endif#define WINDOW_ADDR0	0xFFF00000		/* 512 KiB */#define WINDOW_SIZE0	0x00080000#define BUSWIDTH0	1#define WINDOW_ADDR1	0xFF000000		/* 4 MiB */#define WINDOW_SIZE1	0x00400000#define BUSWIDTH1	8#define MSG_PREFIX "sbc8240:"	/* prefix for our printk()'s */#define MTDID	   "sbc8240-%d"	/* for mtdparts= partitioning */static struct map_info sbc8240_map[2] = {	{		.name           = "sbc8240 Flash Bank #0",		.size           = WINDOW_SIZE0,		.bankwidth       = BUSWIDTH0,	},	{		.name           = "sbc8240 Flash Bank #1",		.size           = WINDOW_SIZE1,		.bankwidth       = BUSWIDTH1,	}};#define NUM_FLASH_BANKS	ARRAY_SIZE(sbc8240_map)/* * The following defines the partition layout of SBC8240 boards. * * See include/linux/mtd/partitions.h for definition of the * mtd_partition structure. * * The *_max_flash_size is the maximum possible mapped flash size * which is not necessarily the actual flash size. It must correspond * to the value specified in the mapping definition defined by the * "struct map_desc *_io_desc" for the corresponding machine. */#ifdef CONFIG_MTD_PARTITIONSstatic struct mtd_partition sbc8240_uboot_partitions [] = {	/* Bank 0 */	{		.name =	"U-boot",			/* U-Boot Firmware	*/		.offset =	0,		.size =	0x00070000,			/*  7 x 64 KiB sectors 	*/		.mask_flags = MTD_WRITEABLE,		/*  force read-only	*/	},	{		.name =	"environment",			/* U-Boot environment	*/		.offset =	0x00070000,		.size =	0x00010000,			/*  1 x 64 KiB sector	*/	},};static struct mtd_partition sbc8240_fs_partitions [] = {	{		.name =	"jffs",				/* JFFS  filesystem	*/		.offset =	0,		.size =	0x003C0000,			/*  4 * 15 * 64KiB	*/	},	{		.name =	"tmp32",		.offset =	0x003C0000,		.size =	0x00020000,			/*  4 * 32KiB		*/	},	{		.name =	"tmp8a",		.offset =	0x003E0000,		.size =	0x00008000,			/*  4 * 8KiB		*/	},	{		.name =	"tmp8b",		.offset =	0x003E8000,		.size =	0x00008000,			/*  4 * 8KiB		*/	},	{		.name =	"tmp16",		.offset =	0x003F0000,		.size =	0x00010000,			/*  4 * 16KiB		*/	}};/* trivial struct to describe partition information */struct mtd_part_def{	int nums;	unsigned char *type;	struct mtd_partition* mtd_part;};static struct mtd_info *sbc8240_mtd[NUM_FLASH_BANKS];static struct mtd_part_def sbc8240_part_banks[NUM_FLASH_BANKS];#endif	/* CONFIG_MTD_PARTITIONS */int __init init_sbc8240_mtd (void){	static struct _cjs {		u_long addr;		u_long size;	} pt[NUM_FLASH_BANKS] = {		{			.addr = WINDOW_ADDR0,			.size = WINDOW_SIZE0		},		{			.addr = WINDOW_ADDR1,			.size = WINDOW_SIZE1		},	};	int devicesfound = 0;	int i,j;	for (i = 0; i < NUM_FLASH_BANKS; i++) {		printk (KERN_NOTICE MSG_PREFIX			"Probing 0x%08lx at 0x%08lx\n", pt[i].size, pt[i].addr);		sbc8240_map[i].map_priv_1 =			(unsigned long) ioremap (pt[i].addr, pt[i].size);		if (!sbc8240_map[i].map_priv_1) {			printk (MSG_PREFIX "failed to ioremap\n");			for (j = 0; j < i; j++) {				iounmap((void *) sbc8240_map[j].map_priv_1);				sbc8240_map[j].map_priv_1 = 0;			}			return -EIO;		}		simple_map_init(&sbc8240_mtd[i]);		sbc8240_mtd[i] = do_map_probe("jedec_probe", &sbc8240_map[i]);		if (sbc8240_mtd[i]) {			sbc8240_mtd[i]->module = THIS_MODULE;			devicesfound++;		} else {			if (sbc8240_map[i].map_priv_1) {				iounmap((void *) sbc8240_map[i].map_priv_1);				sbc8240_map[i].map_priv_1 = 0;			}		}	}	if (!devicesfound) {		printk(KERN_NOTICE MSG_PREFIX		       "No suppported flash chips found!\n");		return -ENXIO;	}#ifdef CONFIG_MTD_PARTITIONS	sbc8240_part_banks[0].mtd_part   = sbc8240_uboot_partitions;	sbc8240_part_banks[0].type       = "static image";	sbc8240_part_banks[0].nums       = ARRAY_SIZE(sbc8240_uboot_partitions);	sbc8240_part_banks[1].mtd_part   = sbc8240_fs_partitions;	sbc8240_part_banks[1].type       = "static file system";	sbc8240_part_banks[1].nums       = ARRAY_SIZE(sbc8240_fs_partitions);	for (i = 0; i < NUM_FLASH_BANKS; i++) {		if (!sbc8240_mtd[i]) continue;		if (sbc8240_part_banks[i].nums == 0) {			printk (KERN_NOTICE MSG_PREFIX				"No partition info available, registering whole device\n");			add_mtd_device(sbc8240_mtd[i]);		} else {			printk (KERN_NOTICE MSG_PREFIX				"Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);			add_mtd_partitions (sbc8240_mtd[i],					    sbc8240_part_banks[i].mtd_part,					    sbc8240_part_banks[i].nums);		}	}#else	printk(KERN_NOTICE MSG_PREFIX	       "Registering %d flash banks at once\n", devicesfound);	for (i = 0; i < devicesfound; i++) {		add_mtd_device(sbc8240_mtd[i]);	}#endif	/* CONFIG_MTD_PARTITIONS */	return devicesfound == 0 ? -ENXIO : 0;}static void __exit cleanup_sbc8240_mtd (void){	int i;	for (i = 0; i < NUM_FLASH_BANKS; i++) {		if (sbc8240_mtd[i]) {			del_mtd_device (sbc8240_mtd[i]);			map_destroy (sbc8240_mtd[i]);		}		if (sbc8240_map[i].map_priv_1) {			iounmap ((void *) sbc8240_map[i].map_priv_1);			sbc8240_map[i].map_priv_1 = 0;		}	}}module_init (init_sbc8240_mtd);module_exit (cleanup_sbc8240_mtd);MODULE_LICENSE ("GPL");MODULE_AUTHOR ("Carolyn Smith <carolyn.smith@tektronix.com>");MODULE_DESCRIPTION ("MTD map driver for SBC8240 boards");

⌨️ 快捷键说明

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