1 /* fortunet.c memory map
3 * $Id: fortunet.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
6 #include <linux/module.h>
7 #include <linux/types.h>
8 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/string.h>
12 #include <linux/mtd/mtd.h>
13 #include <linux/mtd/map.h>
14 #include <linux/mtd/partitions.h>
18 #define MAX_NUM_REGIONS 4
19 #define MAX_NUM_PARTITIONS 8
21 #define DEF_WINDOW_ADDR_PHY 0x00000000
22 #define DEF_WINDOW_SIZE 0x00800000 // 8 Mega Bytes
24 #define MTD_FORTUNET_PK "MTD FortuNet: "
26 #define MAX_NAME_SIZE 128
30 int window_addr_physical;
32 struct map_info map_info;
33 struct mtd_info *mymtd;
34 struct mtd_partition parts[MAX_NUM_PARTITIONS];
35 char map_name[MAX_NAME_SIZE];
36 char parts_name[MAX_NUM_PARTITIONS][MAX_NAME_SIZE];
39 static struct map_region map_regions[MAX_NUM_REGIONS];
40 static int map_regions_set[MAX_NUM_REGIONS] = {0,0,0,0};
41 static int map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0};
45 struct map_info default_map = {
46 .size = DEF_WINDOW_SIZE,
50 static char * __init get_string_option(char *dest,int dest_size,char *sor)
100 static int __init MTD_New_Region(char *line)
102 char string[MAX_NAME_SIZE];
104 get_options (get_string_option(string,sizeof(string),line),6,params);
107 printk(MTD_FORTUNET_PK "Bad parameters for MTD Region "
108 " name,region-number[,base,size,bankwidth,altbankwidth]\n");
111 if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
113 printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
114 params[1],MAX_NUM_REGIONS-1);
117 memset(&map_regions[params[1]],0,sizeof(map_regions[params[1]]));
118 memcpy(&map_regions[params[1]].map_info,
119 &default_map,sizeof(map_regions[params[1]].map_info));
120 map_regions_set[params[1]] = 1;
121 map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY;
122 map_regions[params[1]].altbankwidth = 2;
123 map_regions[params[1]].mymtd = NULL;
124 map_regions[params[1]].map_info.name = map_regions[params[1]].map_name;
125 strcpy(map_regions[params[1]].map_info.name,string);
128 map_regions[params[1]].window_addr_physical = params[2];
132 map_regions[params[1]].map_info.size = params[3];
136 map_regions[params[1]].map_info.bankwidth = params[4];
140 map_regions[params[1]].altbankwidth = params[5];
145 static int __init MTD_New_Partition(char *line)
147 char string[MAX_NAME_SIZE];
149 get_options (get_string_option(string,sizeof(string),line),4,params);
152 printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition "
153 " name,region-number,size,offset\n");
156 if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
158 printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
159 params[1],MAX_NUM_REGIONS-1);
162 if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS)
164 printk(MTD_FORTUNET_PK "Out of space for partition in this region\n");
167 map_regions[params[1]].parts[map_regions_parts[params[1]]].name =
168 map_regions[params[1]]. parts_name[map_regions_parts[params[1]]];
169 strcpy(map_regions[params[1]].parts[map_regions_parts[params[1]]].name,string);
170 map_regions[params[1]].parts[map_regions_parts[params[1]]].size =
172 map_regions[params[1]].parts[map_regions_parts[params[1]]].offset =
174 map_regions[params[1]].parts[map_regions_parts[params[1]]].mask_flags = 0;
175 map_regions_parts[params[1]]++;
179 __setup("MTD_Region=", MTD_New_Region);
180 __setup("MTD_Partition=", MTD_New_Partition);
182 /* Backwards-spelling-compatibility */
183 __setup("MTD_Partion=", MTD_New_Partition);
185 int __init init_fortunet(void)
188 for(iy=ix=0;ix<MAX_NUM_REGIONS;ix++)
190 if(map_regions_parts[ix]&&(!map_regions_set[ix]))
192 printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n",
194 memset(&map_regions[ix],0,sizeof(map_regions[ix]));
195 memcpy(&map_regions[ix].map_info,&default_map,
196 sizeof(map_regions[ix].map_info));
197 map_regions_set[ix] = 1;
198 map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY;
199 map_regions[ix].altbankwidth = 2;
200 map_regions[ix].mymtd = NULL;
201 map_regions[ix].map_info.name = map_regions[ix].map_name;
202 strcpy(map_regions[ix].map_info.name,"FORTUNET");
204 if(map_regions_set[ix])
207 printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically "
208 " address %x size %x\n",
209 map_regions[ix].map_info.name,
210 map_regions[ix].window_addr_physical,
211 map_regions[ix].map_info.size);
213 map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical,
215 map_regions[ix].map_info.virt =
217 map_regions[ix].window_addr_physical,
218 map_regions[ix].map_info.size);
219 if(!map_regions[ix].map_info.virt)
222 printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n",
223 map_regions[ix].map_info.name);
224 for (j = 0 ; j < ix; j++)
225 iounmap(map_regions[j].map_info.virt);
228 simple_map_init(&map_regions[ix].map_info);
230 printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n",
231 map_regions[ix].map_info.name,
232 map_regions[ix].map_info.virt);
233 map_regions[ix].mymtd = do_map_probe("cfi_probe",
234 &map_regions[ix].map_info);
235 if((!map_regions[ix].mymtd)&&(
236 map_regions[ix].altbankwidth!=map_regions[ix].map_info.bankwidth))
238 printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate bankwidth "
240 map_regions[ix].map_info.name);
241 map_regions[ix].map_info.bankwidth =
242 map_regions[ix].altbankwidth;
243 map_regions[ix].mymtd = do_map_probe("cfi_probe",
244 &map_regions[ix].map_info);
246 map_regions[ix].mymtd->owner = THIS_MODULE;
247 add_mtd_partitions(map_regions[ix].mymtd,
248 map_regions[ix].parts,map_regions_parts[ix]);
256 static void __exit cleanup_fortunet(void)
259 for(ix=0;ix<MAX_NUM_REGIONS;ix++)
261 if(map_regions_set[ix])
263 if( map_regions[ix].mymtd )
265 del_mtd_partitions( map_regions[ix].mymtd );
266 map_destroy( map_regions[ix].mymtd );
268 iounmap((void *)map_regions[ix].map_info.virt);
273 module_init(init_fortunet);
274 module_exit(cleanup_fortunet);
276 MODULE_AUTHOR("FortuNet, Inc.");
277 MODULE_DESCRIPTION("MTD map driver for FortuNet boards");