Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[linux-2.6] / drivers / mtd / maps / physmap.c
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
24 static struct mtd_info *mymtd;
25
26 struct 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
34 static struct mtd_partition *mtd_parts;
35 static int                   mtd_parts_nb;
36
37 static int num_physmap_partitions;
38 static struct mtd_partition *physmap_partitions;
39
40 static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL};
41
42 void 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
49 static 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
100 static 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
120 module_init(init_physmap);
121 module_exit(cleanup_physmap);
122
123
124 MODULE_LICENSE("GPL");
125 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
126 MODULE_DESCRIPTION("Generic configurable MTD map driver");