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

📄 dc21285.c

📁 老版本的mtd-snap
💻 C
字号:
/* * MTD map driver for flash on the DC21285 (the StrongARM-110 companion chip) * * (C) 2000  Nicolas Pitre <nico@cam.org> * * This code is GPL *  * $Id: dc21285.c,v 1.22 2004/11/01 13:39:21 rmk Exp $ */#include <linux/config.h>#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/mtd/mtd.h>#include <linux/mtd/map.h>#include <linux/mtd/partitions.h>#include <asm/io.h>#include <asm/hardware/dec21285.h>#include <asm/mach-types.h>static struct mtd_info *dc21285_mtd;#ifdef CONFIG_ARCH_NETWINDER/*  * This is really ugly, but it seams to be the only * realiable way to do it, as the cpld state machine  * is unpredictible. So we have a 25us penalty per * write access. */static void nw_en_write(void){	extern spinlock_t gpio_lock;	unsigned long flags;	/*	 * we want to write a bit pattern XXX1 to Xilinx to enable	 * the write gate, which will be open for about the next 2ms.	 */	spin_lock_irqsave(&gpio_lock, flags);	cpld_modify(1, 1);	spin_unlock_irqrestore(&gpio_lock, flags);	/*	 * let the ISA bus to catch on...	 */	udelay(25);}#else#define nw_en_write() do { } while (0)#endifstatic map_word dc21285_read8(struct map_info *map, unsigned long ofs){	map_word val;	val.x[0] = *(uint8_t*)(map->virt + ofs);	return val;}static map_word dc21285_read16(struct map_info *map, unsigned long ofs){	map_word val;	val.x[0] = *(uint16_t*)(map->virt + ofs);	return val;}static map_word dc21285_read32(struct map_info *map, unsigned long ofs){	map_word val;	val.x[0] = *(uint32_t*)(map->virt + ofs);	return val;}static void dc21285_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len){	memcpy(to, (void*)(map->virt + from), len);}static void dc21285_write8(struct map_info *map, const map_word d, unsigned long adr){	if (machine_is_netwinder())		nw_en_write();	*CSR_ROMWRITEREG = adr & 3;	adr &= ~3;	*(uint8_t*)(map->virt + adr) = d.x[0];}static void dc21285_write16(struct map_info *map, const map_word d, unsigned long adr){	if (machine_is_netwinder())		nw_en_write();	*CSR_ROMWRITEREG = adr & 3;	adr &= ~3;	*(uint16_t*)(map->virt + adr) = d.x[0];}static void dc21285_write32(struct map_info *map, const map_word d, unsigned long adr){	if (machine_is_netwinder())		nw_en_write();	*(uint32_t*)(map->virt + adr) = d.x[0];}static void dc21285_copy_to_32(struct map_info *map, unsigned long to, const void *from, ssize_t len){	while (len > 0) {		map_word d;		d.x[0] = *((uint32_t*)from)++;		dc21285_write32(map, d, to);		to += 4;		len -= 4;	}}static void dc21285_copy_to_16(struct map_info *map, unsigned long to, const void *from, ssize_t len){	while (len > 0) {		map_word d;		d.x[0] = *((uint16_t*)from)++;		dc21285_write16(map, d, to);		to += 2;		len -= 2;	}}static void dc21285_copy_to_8(struct map_info *map, unsigned long to, const void *from, ssize_t len){	map_word d;	d.x[0] = *((uint8_t*)from)++;	dc21285_write8(map, d, to);	to++;	len--;}static struct map_info dc21285_map = {	.name = "DC21285 flash",	.phys = NO_XIP,	.size = 16*1024*1024,	.copy_from = dc21285_copy_from,};/* Partition stuff */#ifdef CONFIG_MTD_PARTITIONSstatic struct mtd_partition *dc21285_parts;static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };#endif  static int __init init_dc21285(void){#ifdef CONFIG_MTD_PARTITIONS	int nrparts;#endif	/* Determine bankwidth */	switch (*CSR_SA110_CNTL & (3<<14)) {		case SA110_CNTL_ROMWIDTH_8: 			dc21285_map.bankwidth = 1;			dc21285_map.read = dc21285_read8;			dc21285_map.write = dc21285_write8;			dc21285_map.copy_to = dc21285_copy_to_8;			break;		case SA110_CNTL_ROMWIDTH_16: 			dc21285_map.bankwidth = 2; 			dc21285_map.read = dc21285_read16;			dc21285_map.write = dc21285_write16;			dc21285_map.copy_to = dc21285_copy_to_16;			break;		case SA110_CNTL_ROMWIDTH_32: 			dc21285_map.bankwidth = 4; 			dc21285_map.read = dc21285_read32;			dc21285_map.write = dc21285_write32;			dc21285_map.copy_to = dc21285_copy_to_32;			break;		default:			printk (KERN_ERR "DC21285 flash: undefined bankwidth\n");			return -ENXIO;	}	printk (KERN_NOTICE "DC21285 flash support (%d-bit bankwidth)\n",		dc21285_map.bankwidth*8);	/* Let's map the flash area */	dc21285_map.virt = ioremap(DC21285_FLASH, 16*1024*1024);	if (!dc21285_map.virt) {		printk("Failed to ioremap\n");		return -EIO;	}	if (machine_is_ebsa285()) {		dc21285_mtd = do_map_probe("cfi_probe", &dc21285_map);	} else {		dc21285_mtd = do_map_probe("jedec_probe", &dc21285_map);	}	if (!dc21285_mtd) {		iounmap(dc21285_map.virt);		return -ENXIO;	}			dc21285_mtd->owner = THIS_MODULE;#ifdef CONFIG_MTD_PARTITIONS	nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);	if (nrparts > 0)		add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts);	else	#endif			add_mtd_device(dc21285_mtd);				if(machine_is_ebsa285()) {		/* 		 * Flash timing is determined with bits 19-16 of the		 * CSR_SA110_CNTL.  The value is the number of wait cycles, or		 * 0 for 16 cycles (the default).  Cycles are 20 ns.		 * Here we use 7 for 140 ns flash chips.		 */		/* access time */		*CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16));		/* burst time */		*CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20));		/* tristate time */		*CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));	}		return 0;}static void __exit cleanup_dc21285(void){#ifdef CONFIG_MTD_PARTITIONS	if (dc21285_parts) {		del_mtd_partitions(dc21285_mtd);		kfree(dc21285_parts);	} else#endif		del_mtd_device(dc21285_mtd);	map_destroy(dc21285_mtd);	iounmap(dc21285_map.virt);}module_init(init_dc21285);module_exit(cleanup_dc21285);MODULE_LICENSE("GPL");MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");MODULE_DESCRIPTION("MTD map driver for DC21285 boards");

⌨️ 快捷键说明

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