#include?<linux/module.h> #include?<linux/types.h> #include?<linux/kernel.h> #include?<linux/init.h> #include?<asm/io.h> #include?<linux/mtd/mtd.h> #include?<linux/mtd/map.h>
#ifdef?CONFIG_MTD_PARTITIONS #include?<linux/mtd/partitions.h> #endif
#define?WINDOW_ADDR?0x10000000?/*?physical?properties?of?flash?*/ #define?WINDOW_SIZE?0x00800000?/*?intel?28F640J3A?8MB?*/ #define?BUSWIDTH?2?/*?data?bus?width?16bits?*/ /*?can?be?"cfi_probe",?"jedec_probe",?"map_rom",?NULL?};?*/ #define?PROBETYPES?{?"cfi_probe",?NULL?}
#define?MSG_PREFIX?"AT91RM9200-NOR:"?/*?prefix?for?our?printk()'s?*/ #define?MTDID?"at91rm9200-%d"?/*?for?mtdparts=?partitioning?*/
static?struct?mtd_info?*mymtd;
struct?map_info?at91rm9200nor_map?=?{ ????????.name?=?"NOR?flash?on?AT91RM9200DK", ????????.size?=?WINDOW_SIZE, ????????.bankwidth?=?BUSWIDTH, ????????.phys?=?WINDOW_ADDR, };
#ifdef?CONFIG_MTD_PARTITIONS
/* ?*?MTD?partitioning?stuff ?*/ static?struct?mtd_partition?at91rm9200nor_partitions[5]?= { ????????{ ????????????????//?U-boot?128KB ????????????????.name?=?"U-boot", ????????????????.size?=?0x20000, ????????????????.offset?=?0 ????????}, ????????{ ????????????????//?uImage?2MB ????????????????.name?=?"Kernel", ????????????????.size?=?0x200000, ????????????????.offset?=?0x20000 ????????}, ????????{ ????????????????//?RootFS?3MB ????????????????.name?=?"RootFS", ????????????????.size?=?0x300000, ????????????????.offset?=?0x220000 ????????}, ????????{ ????????????????//?UserFS ????????????????.name?=?"Jffs2", ????????????????.size?=?0x2C0000, ????????????????.offset?=?0x520000 ????????}, ????????{ ????????????????//?Parameters ????????????????.name?=?"Parameters", ????????????????.offset?=?0x7E0000 ????????}, };
static?const?char?*probes[]?=?{?NULL?};
#endif
static?int?mtd_parts_nb?=?0; static?struct?mtd_partition?*mtd_parts?=?0;
int?__init?init_at91rm9200nor(void) { ????????static?const?char?*rom_probe_types[]?=?PROBETYPES; ????????const?char?**type; ????????const?char?*part_type?=?0;
????????printk(KERN_NOTICE?MSG_PREFIX?"0x%08x?at?0x%08xn", ???????????????WINDOW_SIZE,?WINDOW_ADDR); ????????at91rm9200nor_map.virt?=?ioremap(WINDOW_ADDR,?WINDOW_SIZE);
????????if?(!at91rm9200nor_map.virt)?{ ????????????????printk(MSG_PREFIX?"failed?to?ioremapn"); ????????????????return?-EIO; ????????}
????????simple_map_init(&at91rm9200nor_map);
????????mymtd?=?0; ????????type?=?rom_probe_types; ????????for(;?!mymtd?&&?*type;?type++)?{ ????????????????mymtd?=?do_map_probe(*type,?&at91rm9200nor_map); ????????} ????????if?(mymtd)?{ ????????????????mymtd->owner?=?THIS_MODULE;
#ifdef?CONFIG_MTD_PARTITIONS ????????????????mtd_parts_nb?=?parse_mtd_partitions(mymtd,?probes,?&mtd_parts,?0); ????????????????if?(mtd_parts_nb?>?0) ??????????????????part_type?=?"detected";
????????????????if?(mtd_parts_nb?==?0) ????????????????{ ????????????????????????mtd_parts?=?at91rm9200nor_partitions; ????????????????????????mtd_parts_nb?=?ARRAY_SIZE(at91rm9200nor_partitions); ????????????????????????part_type?=?"static"; ????????????????} #endif ????????????????add_mtd_device(mymtd); ????????????????if?(mtd_parts_nb?==?0) ??????????????????printk(KERN_NOTICE?MSG_PREFIX?"no?partition?info?availablen"); ????????????????else ????????????????{ ????????????????????????printk(KERN_NOTICE?MSG_PREFIX ???????????????????????????????"using?%s?partition?definitionn",?part_type); ?//mymtd为master?mtd_info它不被添加到数组mtd_table[]中,它只用于初始化 ?//每一个分区的mtd_info。而后将每一个分区对应的mtd_info添加到数组mtd_table[] ?//供上层调用。MTD原始设备驱动层的主要工作就是向?mtd_table[]中添加mtd_info。? ????????????????????????add_mtd_partitions(mymtd,?mtd_parts,?mtd_parts_nb); ????????????????} ????????????????return?0; ????????}
????????iounmap((void?*)at91rm9200nor_map.virt); ????????return?-ENXIO; }
static?void?__exit?cleanup_at91rm9200nor(void) { ????????if?(mymtd)?{ ????????????????del_mtd_device(mymtd); ????????????????map_destroy(mymtd); ????????} ????????if?(at91rm9200nor_map.virt)?{ ????????????????iounmap((void?*)at91rm9200nor_map.virt); ????????????????at91rm9200nor_map.virt?=?0; ????????} }
module_init(init_at91rm9200nor); module_exit(cleanup_at91rm9200nor);
MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marius?Groeger?<mag@sysgo.de>"); MODULE_DESCRIPTION("Generic?configurable?MTD?map?driver"); |