at v2.6.14 125 lines 2.9 kB view raw
1/* 2 * $Id: physmap.c,v 1.37 2004/11/28 09:40:40 dwmw2 Exp $ 3 * 4 * Normal mappings of chips in physical memory 5 * 6 * Copyright (C) 2003 MontaVista Software Inc. 7 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net 8 * 9 * 031022 - [jsun] add run-time configure and partition setup 10 */ 11 12#include <linux/module.h> 13#include <linux/types.h> 14#include <linux/kernel.h> 15#include <linux/init.h> 16#include <linux/slab.h> 17#include <asm/io.h> 18#include <linux/mtd/mtd.h> 19#include <linux/mtd/map.h> 20#include <linux/config.h> 21#include <linux/mtd/partitions.h> 22 23static struct mtd_info *mymtd; 24 25struct map_info physmap_map = { 26 .name = "phys_mapped_flash", 27 .phys = CONFIG_MTD_PHYSMAP_START, 28 .size = CONFIG_MTD_PHYSMAP_LEN, 29 .bankwidth = CONFIG_MTD_PHYSMAP_BANKWIDTH, 30}; 31 32#ifdef CONFIG_MTD_PARTITIONS 33static struct mtd_partition *mtd_parts; 34static int mtd_parts_nb; 35 36static int num_physmap_partitions; 37static struct mtd_partition *physmap_partitions; 38 39static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL}; 40 41void physmap_set_partitions(struct mtd_partition *parts, int num_parts) 42{ 43 physmap_partitions=parts; 44 num_physmap_partitions=num_parts; 45} 46#endif /* CONFIG_MTD_PARTITIONS */ 47 48static int __init init_physmap(void) 49{ 50 static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL }; 51 const char **type; 52 53 printk(KERN_NOTICE "physmap flash device: %lx at %lx\n", physmap_map.size, physmap_map.phys); 54 physmap_map.virt = ioremap(physmap_map.phys, physmap_map.size); 55 56 if (!physmap_map.virt) { 57 printk("Failed to ioremap\n"); 58 return -EIO; 59 } 60 61 simple_map_init(&physmap_map); 62 63 mymtd = NULL; 64 type = rom_probe_types; 65 for(; !mymtd && *type; type++) { 66 mymtd = do_map_probe(*type, &physmap_map); 67 } 68 if (mymtd) { 69 mymtd->owner = THIS_MODULE; 70 71#ifdef CONFIG_MTD_PARTITIONS 72 mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, 73 &mtd_parts, 0); 74 75 if (mtd_parts_nb > 0) 76 { 77 add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb); 78 return 0; 79 } 80 81 if (num_physmap_partitions != 0) 82 { 83 printk(KERN_NOTICE 84 "Using physmap partition definition\n"); 85 add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions); 86 return 0; 87 } 88 89#endif 90 add_mtd_device(mymtd); 91 92 return 0; 93 } 94 95 iounmap(physmap_map.virt); 96 return -ENXIO; 97} 98 99static void __exit cleanup_physmap(void) 100{ 101#ifdef CONFIG_MTD_PARTITIONS 102 if (mtd_parts_nb) { 103 del_mtd_partitions(mymtd); 104 kfree(mtd_parts); 105 } else if (num_physmap_partitions) { 106 del_mtd_partitions(mymtd); 107 } else { 108 del_mtd_device(mymtd); 109 } 110#else 111 del_mtd_device(mymtd); 112#endif 113 map_destroy(mymtd); 114 115 iounmap(physmap_map.virt); 116 physmap_map.virt = NULL; 117} 118 119module_init(init_physmap); 120module_exit(cleanup_physmap); 121 122 123MODULE_LICENSE("GPL"); 124MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 125MODULE_DESCRIPTION("Generic configurable MTD map driver");