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");