Merge with /shiny/git/linux-2.6/.git
[linux-2.6] / drivers / mtd / maps / physmap.c
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
23 static struct mtd_info *mymtd;
24
25 struct 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
33 static struct mtd_partition *mtd_parts;
34 static int                   mtd_parts_nb;
35
36 static int num_physmap_partitions;
37 static struct mtd_partition *physmap_partitions;
38
39 static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL};
40
41 void 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
48 static 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
99 static 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
119 module_init(init_physmap);
120 module_exit(cleanup_physmap);
121
122
123 MODULE_LICENSE("GPL");
124 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
125 MODULE_DESCRIPTION("Generic configurable MTD map driver");