at v2.6.16 126 lines 2.9 kB view raw
1/* 2 * $Id: physmap.c,v 1.39 2005/11/29 14:49:36 gleixner 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#include <linux/mtd/physmap.h> 23 24static struct mtd_info *mymtd; 25 26struct map_info physmap_map = { 27 .name = "phys_mapped_flash", 28 .phys = CONFIG_MTD_PHYSMAP_START, 29 .size = CONFIG_MTD_PHYSMAP_LEN, 30 .bankwidth = CONFIG_MTD_PHYSMAP_BANKWIDTH, 31}; 32 33#ifdef CONFIG_MTD_PARTITIONS 34static struct mtd_partition *mtd_parts; 35static int mtd_parts_nb; 36 37static int num_physmap_partitions; 38static struct mtd_partition *physmap_partitions; 39 40static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL}; 41 42void physmap_set_partitions(struct mtd_partition *parts, int num_parts) 43{ 44 physmap_partitions=parts; 45 num_physmap_partitions=num_parts; 46} 47#endif /* CONFIG_MTD_PARTITIONS */ 48 49static int __init init_physmap(void) 50{ 51 static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL }; 52 const char **type; 53 54 printk(KERN_NOTICE "physmap flash device: %lx at %lx\n", physmap_map.size, physmap_map.phys); 55 physmap_map.virt = ioremap(physmap_map.phys, physmap_map.size); 56 57 if (!physmap_map.virt) { 58 printk("Failed to ioremap\n"); 59 return -EIO; 60 } 61 62 simple_map_init(&physmap_map); 63 64 mymtd = NULL; 65 type = rom_probe_types; 66 for(; !mymtd && *type; type++) { 67 mymtd = do_map_probe(*type, &physmap_map); 68 } 69 if (mymtd) { 70 mymtd->owner = THIS_MODULE; 71 72#ifdef CONFIG_MTD_PARTITIONS 73 mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, 74 &mtd_parts, 0); 75 76 if (mtd_parts_nb > 0) 77 { 78 add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb); 79 return 0; 80 } 81 82 if (num_physmap_partitions != 0) 83 { 84 printk(KERN_NOTICE 85 "Using physmap partition definition\n"); 86 add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions); 87 return 0; 88 } 89 90#endif 91 add_mtd_device(mymtd); 92 93 return 0; 94 } 95 96 iounmap(physmap_map.virt); 97 return -ENXIO; 98} 99 100static void __exit cleanup_physmap(void) 101{ 102#ifdef CONFIG_MTD_PARTITIONS 103 if (mtd_parts_nb) { 104 del_mtd_partitions(mymtd); 105 kfree(mtd_parts); 106 } else if (num_physmap_partitions) { 107 del_mtd_partitions(mymtd); 108 } else { 109 del_mtd_device(mymtd); 110 } 111#else 112 del_mtd_device(mymtd); 113#endif 114 map_destroy(mymtd); 115 116 iounmap(physmap_map.virt); 117 physmap_map.virt = NULL; 118} 119 120module_init(init_physmap); 121module_exit(cleanup_physmap); 122 123 124MODULE_LICENSE("GPL"); 125MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 126MODULE_DESCRIPTION("Generic configurable MTD map driver");