diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/mtd/maps/fortunet.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/mtd/maps/fortunet.c')
-rw-r--r-- | drivers/mtd/maps/fortunet.c | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c new file mode 100644 index 000000000000..068bb6a54520 --- /dev/null +++ b/drivers/mtd/maps/fortunet.c | |||
@@ -0,0 +1,271 @@ | |||
1 | /* fortunet.c memory map | ||
2 | * | ||
3 | * $Id: fortunet.c,v 1.9 2004/11/04 13:24:14 gleixner Exp $ | ||
4 | */ | ||
5 | |||
6 | #include <linux/module.h> | ||
7 | #include <linux/types.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <asm/io.h> | ||
11 | #include <linux/mtd/mtd.h> | ||
12 | #include <linux/mtd/map.h> | ||
13 | #include <linux/mtd/partitions.h> | ||
14 | |||
15 | #define MAX_NUM_REGIONS 4 | ||
16 | #define MAX_NUM_PARTITIONS 8 | ||
17 | |||
18 | #define DEF_WINDOW_ADDR_PHY 0x00000000 | ||
19 | #define DEF_WINDOW_SIZE 0x00800000 // 8 Mega Bytes | ||
20 | |||
21 | #define MTD_FORTUNET_PK "MTD FortuNet: " | ||
22 | |||
23 | #define MAX_NAME_SIZE 128 | ||
24 | |||
25 | struct map_region | ||
26 | { | ||
27 | int window_addr_physical; | ||
28 | int altbankwidth; | ||
29 | struct map_info map_info; | ||
30 | struct mtd_info *mymtd; | ||
31 | struct mtd_partition parts[MAX_NUM_PARTITIONS]; | ||
32 | char map_name[MAX_NAME_SIZE]; | ||
33 | char parts_name[MAX_NUM_PARTITIONS][MAX_NAME_SIZE]; | ||
34 | }; | ||
35 | |||
36 | static struct map_region map_regions[MAX_NUM_REGIONS]; | ||
37 | static int map_regions_set[MAX_NUM_REGIONS] = {0,0,0,0}; | ||
38 | static int map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0}; | ||
39 | |||
40 | |||
41 | |||
42 | struct map_info default_map = { | ||
43 | .size = DEF_WINDOW_SIZE, | ||
44 | .bankwidth = 4, | ||
45 | }; | ||
46 | |||
47 | static char * __init get_string_option(char *dest,int dest_size,char *sor) | ||
48 | { | ||
49 | if(!dest_size) | ||
50 | return sor; | ||
51 | dest_size--; | ||
52 | while(*sor) | ||
53 | { | ||
54 | if(*sor==',') | ||
55 | { | ||
56 | sor++; | ||
57 | break; | ||
58 | } | ||
59 | else if(*sor=='\"') | ||
60 | { | ||
61 | sor++; | ||
62 | while(*sor) | ||
63 | { | ||
64 | if(*sor=='\"') | ||
65 | { | ||
66 | sor++; | ||
67 | break; | ||
68 | } | ||
69 | *dest = *sor; | ||
70 | dest++; | ||
71 | sor++; | ||
72 | dest_size--; | ||
73 | if(!dest_size) | ||
74 | { | ||
75 | *dest = 0; | ||
76 | return sor; | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | else | ||
81 | { | ||
82 | *dest = *sor; | ||
83 | dest++; | ||
84 | sor++; | ||
85 | dest_size--; | ||
86 | if(!dest_size) | ||
87 | { | ||
88 | *dest = 0; | ||
89 | return sor; | ||
90 | } | ||
91 | } | ||
92 | } | ||
93 | *dest = 0; | ||
94 | return sor; | ||
95 | } | ||
96 | |||
97 | static int __init MTD_New_Region(char *line) | ||
98 | { | ||
99 | char string[MAX_NAME_SIZE]; | ||
100 | int params[6]; | ||
101 | get_options (get_string_option(string,sizeof(string),line),6,params); | ||
102 | if(params[0]<1) | ||
103 | { | ||
104 | printk(MTD_FORTUNET_PK "Bad parameters for MTD Region " | ||
105 | " name,region-number[,base,size,bankwidth,altbankwidth]\n"); | ||
106 | return 1; | ||
107 | } | ||
108 | if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS)) | ||
109 | { | ||
110 | printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n", | ||
111 | params[1],MAX_NUM_REGIONS-1); | ||
112 | return 1; | ||
113 | } | ||
114 | memset(&map_regions[params[1]],0,sizeof(map_regions[params[1]])); | ||
115 | memcpy(&map_regions[params[1]].map_info, | ||
116 | &default_map,sizeof(map_regions[params[1]].map_info)); | ||
117 | map_regions_set[params[1]] = 1; | ||
118 | map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY; | ||
119 | map_regions[params[1]].altbankwidth = 2; | ||
120 | map_regions[params[1]].mymtd = NULL; | ||
121 | map_regions[params[1]].map_info.name = map_regions[params[1]].map_name; | ||
122 | strcpy(map_regions[params[1]].map_info.name,string); | ||
123 | if(params[0]>1) | ||
124 | { | ||
125 | map_regions[params[1]].window_addr_physical = params[2]; | ||
126 | } | ||
127 | if(params[0]>2) | ||
128 | { | ||
129 | map_regions[params[1]].map_info.size = params[3]; | ||
130 | } | ||
131 | if(params[0]>3) | ||
132 | { | ||
133 | map_regions[params[1]].map_info.bankwidth = params[4]; | ||
134 | } | ||
135 | if(params[0]>4) | ||
136 | { | ||
137 | map_regions[params[1]].altbankwidth = params[5]; | ||
138 | } | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | static int __init MTD_New_Partition(char *line) | ||
143 | { | ||
144 | char string[MAX_NAME_SIZE]; | ||
145 | int params[4]; | ||
146 | get_options (get_string_option(string,sizeof(string),line),4,params); | ||
147 | if(params[0]<3) | ||
148 | { | ||
149 | printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition " | ||
150 | " name,region-number,size,offset\n"); | ||
151 | return 1; | ||
152 | } | ||
153 | if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS)) | ||
154 | { | ||
155 | printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n", | ||
156 | params[1],MAX_NUM_REGIONS-1); | ||
157 | return 1; | ||
158 | } | ||
159 | if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS) | ||
160 | { | ||
161 | printk(MTD_FORTUNET_PK "Out of space for partition in this region\n"); | ||
162 | return 1; | ||
163 | } | ||
164 | map_regions[params[1]].parts[map_regions_parts[params[1]]].name = | ||
165 | map_regions[params[1]]. parts_name[map_regions_parts[params[1]]]; | ||
166 | strcpy(map_regions[params[1]].parts[map_regions_parts[params[1]]].name,string); | ||
167 | map_regions[params[1]].parts[map_regions_parts[params[1]]].size = | ||
168 | params[2]; | ||
169 | map_regions[params[1]].parts[map_regions_parts[params[1]]].offset = | ||
170 | params[3]; | ||
171 | map_regions[params[1]].parts[map_regions_parts[params[1]]].mask_flags = 0; | ||
172 | map_regions_parts[params[1]]++; | ||
173 | return 1; | ||
174 | } | ||
175 | |||
176 | __setup("MTD_Region=", MTD_New_Region); | ||
177 | __setup("MTD_Partition=", MTD_New_Partition); | ||
178 | |||
179 | /* Backwards-spelling-compatibility */ | ||
180 | __setup("MTD_Partion=", MTD_New_Partition); | ||
181 | |||
182 | int __init init_fortunet(void) | ||
183 | { | ||
184 | int ix,iy; | ||
185 | for(iy=ix=0;ix<MAX_NUM_REGIONS;ix++) | ||
186 | { | ||
187 | if(map_regions_parts[ix]&&(!map_regions_set[ix])) | ||
188 | { | ||
189 | printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n", | ||
190 | ix); | ||
191 | memset(&map_regions[ix],0,sizeof(map_regions[ix])); | ||
192 | memcpy(&map_regions[ix].map_info,&default_map, | ||
193 | sizeof(map_regions[ix].map_info)); | ||
194 | map_regions_set[ix] = 1; | ||
195 | map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY; | ||
196 | map_regions[ix].altbankwidth = 2; | ||
197 | map_regions[ix].mymtd = NULL; | ||
198 | map_regions[ix].map_info.name = map_regions[ix].map_name; | ||
199 | strcpy(map_regions[ix].map_info.name,"FORTUNET"); | ||
200 | } | ||
201 | if(map_regions_set[ix]) | ||
202 | { | ||
203 | iy++; | ||
204 | printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically " | ||
205 | " address %x size %x\n", | ||
206 | map_regions[ix].map_info.name, | ||
207 | map_regions[ix].window_addr_physical, | ||
208 | map_regions[ix].map_info.size); | ||
209 | |||
210 | map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical, | ||
211 | |||
212 | map_regions[ix].map_info.virt = | ||
213 | ioremap_nocache( | ||
214 | map_regions[ix].window_addr_physical, | ||
215 | map_regions[ix].map_info.size); | ||
216 | if(!map_regions[ix].map_info.virt) | ||
217 | { | ||
218 | printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n", | ||
219 | map_regions[ix].map_info.name); | ||
220 | return -ENXIO; | ||
221 | } | ||
222 | simple_map_init(&map_regions[ix].map_info); | ||
223 | |||
224 | printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n", | ||
225 | map_regions[ix].map_info.name, | ||
226 | map_regions[ix].map_info.virt); | ||
227 | map_regions[ix].mymtd = do_map_probe("cfi_probe", | ||
228 | &map_regions[ix].map_info); | ||
229 | if((!map_regions[ix].mymtd)&&( | ||
230 | map_regions[ix].altbankwidth!=map_regions[ix].map_info.bankwidth)) | ||
231 | { | ||
232 | printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate bankwidth " | ||
233 | "for %s flash.\n", | ||
234 | map_regions[ix].map_info.name); | ||
235 | map_regions[ix].map_info.bankwidth = | ||
236 | map_regions[ix].altbankwidth; | ||
237 | map_regions[ix].mymtd = do_map_probe("cfi_probe", | ||
238 | &map_regions[ix].map_info); | ||
239 | } | ||
240 | map_regions[ix].mymtd->owner = THIS_MODULE; | ||
241 | add_mtd_partitions(map_regions[ix].mymtd, | ||
242 | map_regions[ix].parts,map_regions_parts[ix]); | ||
243 | } | ||
244 | } | ||
245 | if(iy) | ||
246 | return 0; | ||
247 | return -ENXIO; | ||
248 | } | ||
249 | |||
250 | static void __exit cleanup_fortunet(void) | ||
251 | { | ||
252 | int ix; | ||
253 | for(ix=0;ix<MAX_NUM_REGIONS;ix++) | ||
254 | { | ||
255 | if(map_regions_set[ix]) | ||
256 | { | ||
257 | if( map_regions[ix].mymtd ) | ||
258 | { | ||
259 | del_mtd_partitions( map_regions[ix].mymtd ); | ||
260 | map_destroy( map_regions[ix].mymtd ); | ||
261 | } | ||
262 | iounmap((void *)map_regions[ix].map_info.virt); | ||
263 | } | ||
264 | } | ||
265 | } | ||
266 | |||
267 | module_init(init_fortunet); | ||
268 | module_exit(cleanup_fortunet); | ||
269 | |||
270 | MODULE_AUTHOR("FortuNet, Inc."); | ||
271 | MODULE_DESCRIPTION("MTD map driver for FortuNet boards"); | ||