Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
2b9175c1 | 2 | * $Id: physmap.c,v 1.39 2005/11/29 14:49:36 gleixner Exp $ |
1da177e4 LT |
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> | |
2b9175c1 | 22 | #include <linux/mtd/physmap.h> |
1da177e4 LT |
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 | |
69f34c98 | 73 | mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, |
1da177e4 LT |
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 | ||
69f34c98 | 82 | if (num_physmap_partitions != 0) |
1da177e4 | 83 | { |
69f34c98 | 84 | printk(KERN_NOTICE |
1da177e4 LT |
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"); |