1 /* fortunet.c memory map
3 * $Id: fortunet.c,v 1.2 2002/10/14 12:50:22 rmk Exp $
6 #include <linux/module.h>
7 #include <linux/types.h>
8 #include <linux/kernel.h>
10 #include <linux/mtd/mtd.h>
11 #include <linux/mtd/map.h>
12 #include <linux/mtd/partitions.h>
14 #define MAX_NUM_REGIONS 4
15 #define MAX_NUM_PARTITIONS 8
17 #define DEF_WINDOW_ADDR_PHY 0x00000000
18 #define DEF_WINDOW_SIZE 0x00800000 // 8 Mega Bytes
20 #define MTD_FORTUNET_PK "MTD FortuNet: "
22 #define MAX_NAME_SIZE 128
26 int window_addr_phyical;
28 struct map_info map_info;
29 struct mtd_info *mymtd;
30 struct mtd_partition parts[MAX_NUM_PARTITIONS];
31 char map_name[MAX_NAME_SIZE];
32 char parts_name[MAX_NUM_PARTITIONS][MAX_NAME_SIZE];
35 static struct map_region map_regions[MAX_NUM_REGIONS];
36 static int map_regions_set[MAX_NUM_REGIONS] = {0,0,0,0};
37 static int map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0};
40 __u8 fortunet_read8(struct map_info *map, unsigned long ofs)
42 return *(__u8 *)(map->map_priv_1 + ofs);
45 __u16 fortunet_read16(struct map_info *map, unsigned long ofs)
47 return *(__u16 *)(map->map_priv_1 + ofs);
50 __u32 fortunet_read32(struct map_info *map, unsigned long ofs)
52 return *(__u32 *)(map->map_priv_1 + ofs);
55 void fortunet_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
57 memcpy(to, (void *)(map->map_priv_1 + from), len);
60 void fortunet_write8(struct map_info *map, __u8 d, unsigned long adr)
62 *(__u8 *)(map->map_priv_1 + adr) = d;
65 void fortunet_write16(struct map_info *map, __u16 d, unsigned long adr)
67 *(__u16 *)(map->map_priv_1 + adr) = d;
70 void fortunet_write32(struct map_info *map, __u32 d, unsigned long adr)
72 *(__u32 *)(map->map_priv_1 + adr) = d;
75 void fortunet_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
77 memcpy((void *)(map->map_priv_1 + to), from, len);
80 struct map_info default_map = {
81 size: DEF_WINDOW_SIZE,
83 read8: fortunet_read8,
84 read16: fortunet_read16,
85 read32: fortunet_read32,
86 copy_from: fortunet_copy_from,
87 write8: fortunet_write8,
88 write16: fortunet_write16,
89 write32: fortunet_write32,
90 copy_to: fortunet_copy_to
93 static char * __init get_string_option(char *dest,int dest_size,char *sor)
143 static int __init MTD_New_Region(char *line)
145 char string[MAX_NAME_SIZE];
147 get_options (get_string_option(string,sizeof(string),line),6,params);
150 printk(MTD_FORTUNET_PK "Bad paramters for MTD Region "
151 " name,region-number[,base,size,buswidth,altbuswidth]\n");
154 if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
156 printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
157 params[1],MAX_NUM_REGIONS-1);
160 memset(&map_regions[params[1]],0,sizeof(map_regions[params[1]]));
161 memcpy(&map_regions[params[1]].map_info,
162 &default_map,sizeof(map_regions[params[1]].map_info));
163 map_regions_set[params[1]] = 1;
164 map_regions[params[1]].window_addr_phyical = DEF_WINDOW_ADDR_PHY;
165 map_regions[params[1]].altbuswidth = 2;
166 map_regions[params[1]].mymtd = NULL;
167 map_regions[params[1]].map_info.name = map_regions[params[1]].map_name;
168 strcpy(map_regions[params[1]].map_info.name,string);
171 map_regions[params[1]].window_addr_phyical = params[2];
175 map_regions[params[1]].map_info.size = params[3];
179 map_regions[params[1]].map_info.buswidth = params[4];
183 map_regions[params[1]].altbuswidth = params[5];
188 static int __init MTD_New_Partion(char *line)
190 char string[MAX_NAME_SIZE];
192 get_options (get_string_option(string,sizeof(string),line),4,params);
195 printk(MTD_FORTUNET_PK "Bad paramters for MTD Partion "
196 " name,region-number,size,offset\n");
199 if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
201 printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
202 params[1],MAX_NUM_REGIONS-1);
205 if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS)
207 printk(MTD_FORTUNET_PK "Out of space for partion in this region\n");
210 map_regions[params[1]].parts[map_regions_parts[params[1]]].name =
211 map_regions[params[1]]. parts_name[map_regions_parts[params[1]]];
212 strcpy(map_regions[params[1]].parts[map_regions_parts[params[1]]].name,string);
213 map_regions[params[1]].parts[map_regions_parts[params[1]]].size =
215 map_regions[params[1]].parts[map_regions_parts[params[1]]].offset =
217 map_regions[params[1]].parts[map_regions_parts[params[1]]].mask_flags = 0;
218 map_regions_parts[params[1]]++;
222 __setup("MTD_Region=", MTD_New_Region);
223 __setup("MTD_Partion=", MTD_New_Partion);
225 int __init init_fortunet(void)
228 for(iy=ix=0;ix<MAX_NUM_REGIONS;ix++)
230 if(map_regions_parts[ix]&&(!map_regions_set[ix]))
232 printk(MTD_FORTUNET_PK "Region %d is not setup (Seting to default)\n",
234 memset(&map_regions[ix],0,sizeof(map_regions[ix]));
235 memcpy(&map_regions[ix].map_info,&default_map,
236 sizeof(map_regions[ix].map_info));
237 map_regions_set[ix] = 1;
238 map_regions[ix].window_addr_phyical = DEF_WINDOW_ADDR_PHY;
239 map_regions[ix].altbuswidth = 2;
240 map_regions[ix].mymtd = NULL;
241 map_regions[ix].map_info.name = map_regions[ix].map_name;
242 strcpy(map_regions[ix].map_info.name,"FORTUNET");
244 if(map_regions_set[ix])
247 printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at phyicaly "
248 " address %x size %x\n",
249 map_regions[ix].map_info.name,
250 map_regions[ix].window_addr_phyical,
251 map_regions[ix].map_info.size);
252 map_regions[ix].map_info.map_priv_1 =
253 (int)ioremap_nocache(
254 map_regions[ix].window_addr_phyical,
255 map_regions[ix].map_info.size);
256 if(!map_regions[ix].map_info.map_priv_1)
258 printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n",
259 map_regions[ix].map_info.name);
262 printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is veritualy at: %x\n",
263 map_regions[ix].map_info.name,
264 map_regions[ix].map_info.map_priv_1);
265 map_regions[ix].mymtd = do_map_probe("cfi_probe",
266 &map_regions[ix].map_info);
267 if((!map_regions[ix].mymtd)&&(
268 map_regions[ix].altbuswidth!=map_regions[ix].map_info.buswidth))
270 printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternet buswidth "
272 map_regions[ix].map_info.name);
273 map_regions[ix].map_info.buswidth =
274 map_regions[ix].altbuswidth;
275 map_regions[ix].mymtd = do_map_probe("cfi_probe",
276 &map_regions[ix].map_info);
278 map_regions[ix].mymtd->module = THIS_MODULE;
279 add_mtd_partitions(map_regions[ix].mymtd,
280 map_regions[ix].parts,map_regions_parts[ix]);
288 static void __exit cleanup_fortunet(void)
291 for(ix=0;ix<MAX_NUM_REGIONS;ix++)
293 if(map_regions_set[ix])
295 if( map_regions[ix].mymtd )
297 del_mtd_partitions( map_regions[ix].mymtd );
298 map_destroy( map_regions[ix].mymtd );
300 iounmap((void *)map_regions[ix].map_info.map_priv_1);
305 module_init(init_fortunet);
306 module_exit(cleanup_fortunet);
308 MODULE_AUTHOR("FortuNet, Inc.");
309 MODULE_DESCRIPTION("MTD map driver for FortuNet boards");