/* fortunet.c memory map
 *
 * $Id: fortunet.c,v 1.9 2004/11/04 13:24:14 gleixner Exp $
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>

#define MAX_NUM_REGIONS		4
#define MAX_NUM_PARTITIONS	8

#define DEF_WINDOW_ADDR_PHY	0x00000000
#define DEF_WINDOW_SIZE		0x00800000		// 8 Mega Bytes

#define MTD_FORTUNET_PK		"MTD FortuNet: "

#define MAX_NAME_SIZE		128

struct map_region
{
	int			window_addr_physical;
	int			altbankwidth;
	struct map_info		map_info;
	struct mtd_info		*mymtd;
	struct mtd_partition	parts[MAX_NUM_PARTITIONS];
	char			map_name[MAX_NAME_SIZE];
	char			parts_name[MAX_NUM_PARTITIONS][MAX_NAME_SIZE];
};

static struct map_region	map_regions[MAX_NUM_REGIONS];
static int			map_regions_set[MAX_NUM_REGIONS] = {0,0,0,0};
static int			map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0};



struct map_info default_map = {
	.size = DEF_WINDOW_SIZE,
	.bankwidth = 4,
};

static char * __init get_string_option(char *dest,int dest_size,char *sor)
{
	if(!dest_size)
		return sor;
	dest_size--;
	while(*sor)
	{
		if(*sor==',')
		{
			sor++;
			break;
		}
		else if(*sor=='\"')
		{
			sor++;
			while(*sor)
			{
				if(*sor=='\"')
				{
					sor++;
					break;
				}
				*dest = *sor;
				dest++;
				sor++;
				dest_size--;
				if(!dest_size)
				{
					*dest = 0;
					return sor;
				}
			}
		}
		else
		{
			*dest = *sor;
			dest++;
			sor++;
			dest_size--;
			if(!dest_size)
			{
				*dest = 0;
				return sor;
			}
		}
	}
	*dest = 0;
	return sor;
}

static int __init MTD_New_Region(char *line)
{
	char	string[MAX_NAME_SIZE];
	int	params[6];
	get_options (get_string_option(string,sizeof(string),line),6,params);
	if(params[0]<1)
	{
		printk(MTD_FORTUNET_PK "Bad parameters for MTD Region "
			" name,region-number[,base,size,bankwidth,altbankwidth]\n");
		return 1;
	}
	if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
	{
		printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
			params[1],MAX_NUM_REGIONS-1);
		return 1;
	}
	memset(&map_regions[params[1]],0,sizeof(map_regions[params[1]]));
	memcpy(&map_regions[params[1]].map_info,
		&default_map,sizeof(map_regions[params[1]].map_info));
        map_regions_set[params[1]] = 1;
        map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY;
        map_regions[params[1]].altbankwidth = 2;
        map_regions[params[1]].mymtd = NULL;
	map_regions[params[1]].map_info.name = map_regions[params[1]].map_name;
	strcpy(map_regions[params[1]].map_info.name,string);
	if(params[0]>1)
	{
		map_regions[params[1]].window_addr_physical = params[2];
	}
	if(params[0]>2)
	{
		map_regions[params[1]].map_info.size = params[3];
	}
	if(params[0]>3)
	{
		map_regions[params[1]].map_info.bankwidth = params[4];
	}
	if(params[0]>4)
	{
		map_regions[params[1]].altbankwidth = params[5];
	}
	return 1;
}

static int __init MTD_New_Partition(char *line)
{
	char	string[MAX_NAME_SIZE];
	int	params[4];
	get_options (get_string_option(string,sizeof(string),line),4,params);
	if(params[0]<3)
	{
		printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition "
			" name,region-number,size,offset\n");
		return 1;
	}
	if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
	{
		printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
			params[1],MAX_NUM_REGIONS-1);
		return 1;
	}
	if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS)
	{
		printk(MTD_FORTUNET_PK "Out of space for partition in this region\n");
		return 1;
	}
	map_regions[params[1]].parts[map_regions_parts[params[1]]].name =
		map_regions[params[1]].	parts_name[map_regions_parts[params[1]]];
	strcpy(map_regions[params[1]].parts[map_regions_parts[params[1]]].name,string);
	map_regions[params[1]].parts[map_regions_parts[params[1]]].size =
		params[2];
	map_regions[params[1]].parts[map_regions_parts[params[1]]].offset =
		params[3];
	map_regions[params[1]].parts[map_regions_parts[params[1]]].mask_flags = 0;
	map_regions_parts[params[1]]++;
	return 1;
}

__setup("MTD_Region=", MTD_New_Region);
__setup("MTD_Partition=", MTD_New_Partition);

/* Backwards-spelling-compatibility */
__setup("MTD_Partion=", MTD_New_Partition);

int __init init_fortunet(void)
{
	int	ix,iy;
	for(iy=ix=0;ix<MAX_NUM_REGIONS;ix++)
	{
		if(map_regions_parts[ix]&&(!map_regions_set[ix]))
		{
			printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n",
				ix);
			memset(&map_regions[ix],0,sizeof(map_regions[ix]));
			memcpy(&map_regions[ix].map_info,&default_map,
				sizeof(map_regions[ix].map_info));
			map_regions_set[ix] = 1;
			map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY;
			map_regions[ix].altbankwidth = 2;
			map_regions[ix].mymtd = NULL;
			map_regions[ix].map_info.name = map_regions[ix].map_name;
			strcpy(map_regions[ix].map_info.name,"FORTUNET");
		}
		if(map_regions_set[ix])
		{
			iy++;
			printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically "
				" address %x size %x\n",
				map_regions[ix].map_info.name,
				map_regions[ix].window_addr_physical,
				map_regions[ix].map_info.size);

			map_regions[ix].map_info.phys =	map_regions[ix].window_addr_physical,

			map_regions[ix].map_info.virt = 
				ioremap_nocache(
				map_regions[ix].window_addr_physical,
				map_regions[ix].map_info.size);
			if(!map_regions[ix].map_info.virt)
			{
				printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n",
					map_regions[ix].map_info.name);
				return -ENXIO;
			}
			simple_map_init(&map_regions[ix].map_info);

			printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n",
				map_regions[ix].map_info.name,
				map_regions[ix].map_info.virt);
			map_regions[ix].mymtd = do_map_probe("cfi_probe",
				&map_regions[ix].map_info);
			if((!map_regions[ix].mymtd)&&(
				map_regions[ix].altbankwidth!=map_regions[ix].map_info.bankwidth))
			{
				printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate bankwidth "
					"for %s flash.\n",
					map_regions[ix].map_info.name);
				map_regions[ix].map_info.bankwidth =
					map_regions[ix].altbankwidth;
				map_regions[ix].mymtd = do_map_probe("cfi_probe",
					&map_regions[ix].map_info);
			}
			map_regions[ix].mymtd->owner = THIS_MODULE;
			add_mtd_partitions(map_regions[ix].mymtd,
				map_regions[ix].parts,map_regions_parts[ix]);
		}
	}
	if(iy)
		return 0;
	return -ENXIO;
}

static void __exit cleanup_fortunet(void)
{
	int	ix;
	for(ix=0;ix<MAX_NUM_REGIONS;ix++)
	{
		if(map_regions_set[ix])
		{
			if( map_regions[ix].mymtd )
			{
				del_mtd_partitions( map_regions[ix].mymtd );
				map_destroy( map_regions[ix].mymtd );
			}
			iounmap((void *)map_regions[ix].map_info.virt);
		}
	}
}

module_init(init_fortunet);
module_exit(cleanup_fortunet);

MODULE_AUTHOR("FortuNet, Inc.");
MODULE_DESCRIPTION("MTD map driver for FortuNet boards");
