Linux-2.6.12-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / mtd / maps / fortunet.c
blob068bb6a545201f3b5b259f5df5205167b5c45143
1 /* fortunet.c memory map
3 * $Id: fortunet.c,v 1.9 2004/11/04 13:24:14 gleixner Exp $
4 */
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>
15 #define MAX_NUM_REGIONS 4
16 #define MAX_NUM_PARTITIONS 8
18 #define DEF_WINDOW_ADDR_PHY 0x00000000
19 #define DEF_WINDOW_SIZE 0x00800000 // 8 Mega Bytes
21 #define MTD_FORTUNET_PK "MTD FortuNet: "
23 #define MAX_NAME_SIZE 128
25 struct map_region
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];
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};
42 struct map_info default_map = {
43 .size = DEF_WINDOW_SIZE,
44 .bankwidth = 4,
47 static char * __init get_string_option(char *dest,int dest_size,char *sor)
49 if(!dest_size)
50 return sor;
51 dest_size--;
52 while(*sor)
54 if(*sor==',')
56 sor++;
57 break;
59 else if(*sor=='\"')
61 sor++;
62 while(*sor)
64 if(*sor=='\"')
66 sor++;
67 break;
69 *dest = *sor;
70 dest++;
71 sor++;
72 dest_size--;
73 if(!dest_size)
75 *dest = 0;
76 return sor;
80 else
82 *dest = *sor;
83 dest++;
84 sor++;
85 dest_size--;
86 if(!dest_size)
88 *dest = 0;
89 return sor;
93 *dest = 0;
94 return sor;
97 static int __init MTD_New_Region(char *line)
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)
104 printk(MTD_FORTUNET_PK "Bad parameters for MTD Region "
105 " name,region-number[,base,size,bankwidth,altbankwidth]\n");
106 return 1;
108 if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
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;
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)
125 map_regions[params[1]].window_addr_physical = params[2];
127 if(params[0]>2)
129 map_regions[params[1]].map_info.size = params[3];
131 if(params[0]>3)
133 map_regions[params[1]].map_info.bankwidth = params[4];
135 if(params[0]>4)
137 map_regions[params[1]].altbankwidth = params[5];
139 return 1;
142 static int __init MTD_New_Partition(char *line)
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)
149 printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition "
150 " name,region-number,size,offset\n");
151 return 1;
153 if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
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;
159 if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS)
161 printk(MTD_FORTUNET_PK "Out of space for partition in this region\n");
162 return 1;
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;
176 __setup("MTD_Region=", MTD_New_Region);
177 __setup("MTD_Partition=", MTD_New_Partition);
179 /* Backwards-spelling-compatibility */
180 __setup("MTD_Partion=", MTD_New_Partition);
182 int __init init_fortunet(void)
184 int ix,iy;
185 for(iy=ix=0;ix<MAX_NUM_REGIONS;ix++)
187 if(map_regions_parts[ix]&&(!map_regions_set[ix]))
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");
201 if(map_regions_set[ix])
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);
210 map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical,
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)
218 printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n",
219 map_regions[ix].map_info.name);
220 return -ENXIO;
222 simple_map_init(&map_regions[ix].map_info);
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))
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);
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]);
245 if(iy)
246 return 0;
247 return -ENXIO;
250 static void __exit cleanup_fortunet(void)
252 int ix;
253 for(ix=0;ix<MAX_NUM_REGIONS;ix++)
255 if(map_regions_set[ix])
257 if( map_regions[ix].mymtd )
259 del_mtd_partitions( map_regions[ix].mymtd );
260 map_destroy( map_regions[ix].mymtd );
262 iounmap((void *)map_regions[ix].map_info.virt);
267 module_init(init_fortunet);
268 module_exit(cleanup_fortunet);
270 MODULE_AUTHOR("FortuNet, Inc.");
271 MODULE_DESCRIPTION("MTD map driver for FortuNet boards");