Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1/* fortunet.c memory map
  2 *
  3 */
  4
  5#include <linux/module.h>
  6#include <linux/types.h>
  7#include <linux/kernel.h>
  8#include <linux/init.h>
  9#include <linux/string.h>
 10
 11#include <linux/mtd/mtd.h>
 12#include <linux/mtd/map.h>
 13#include <linux/mtd/partitions.h>
 14
 15#include <asm/io.h>
 16
 17#define MAX_NUM_REGIONS		4
 18#define MAX_NUM_PARTITIONS	8
 19
 20#define DEF_WINDOW_ADDR_PHY	0x00000000
 21#define DEF_WINDOW_SIZE		0x00800000		// 8 Mega Bytes
 22
 23#define MTD_FORTUNET_PK		"MTD FortuNet: "
 24
 25#define MAX_NAME_SIZE		128
 26
 27struct map_region
 28{
 29	int			window_addr_physical;
 30	int			altbankwidth;
 31	struct map_info		map_info;
 32	struct mtd_info		*mymtd;
 33	struct mtd_partition	parts[MAX_NUM_PARTITIONS];
 34	char			map_name[MAX_NAME_SIZE];
 35	char			parts_name[MAX_NUM_PARTITIONS][MAX_NAME_SIZE];
 36};
 37
 38static struct map_region	map_regions[MAX_NUM_REGIONS];
 39static int			map_regions_set[MAX_NUM_REGIONS] = {0,0,0,0};
 40static int			map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0};
 41
 42
 43
 44struct map_info default_map = {
 45	.size = DEF_WINDOW_SIZE,
 46	.bankwidth = 4,
 47};
 48
 49static char * __init get_string_option(char *dest,int dest_size,char *sor)
 50{
 51	if(!dest_size)
 52		return sor;
 53	dest_size--;
 54	while(*sor)
 55	{
 56		if(*sor==',')
 57		{
 58			sor++;
 59			break;
 60		}
 61		else if(*sor=='\"')
 62		{
 63			sor++;
 64			while(*sor)
 65			{
 66				if(*sor=='\"')
 67				{
 68					sor++;
 69					break;
 70				}
 71				*dest = *sor;
 72				dest++;
 73				sor++;
 74				dest_size--;
 75				if(!dest_size)
 76				{
 77					*dest = 0;
 78					return sor;
 79				}
 80			}
 81		}
 82		else
 83		{
 84			*dest = *sor;
 85			dest++;
 86			sor++;
 87			dest_size--;
 88			if(!dest_size)
 89			{
 90				*dest = 0;
 91				return sor;
 92			}
 93		}
 94	}
 95	*dest = 0;
 96	return sor;
 97}
 98
 99static int __init MTD_New_Region(char *line)
100{
101	char	string[MAX_NAME_SIZE];
102	int	params[6];
103	get_options (get_string_option(string,sizeof(string),line),6,params);
104	if(params[0]<1)
105	{
106		printk(MTD_FORTUNET_PK "Bad parameters for MTD Region "
107			" name,region-number[,base,size,bankwidth,altbankwidth]\n");
108		return 1;
109	}
110	if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
111	{
112		printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
113			params[1],MAX_NUM_REGIONS-1);
114		return 1;
115	}
116	memset(&map_regions[params[1]],0,sizeof(map_regions[params[1]]));
117	memcpy(&map_regions[params[1]].map_info,
118		&default_map,sizeof(map_regions[params[1]].map_info));
119        map_regions_set[params[1]] = 1;
120        map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY;
121        map_regions[params[1]].altbankwidth = 2;
122        map_regions[params[1]].mymtd = NULL;
123	map_regions[params[1]].map_info.name = map_regions[params[1]].map_name;
124	strcpy(map_regions[params[1]].map_info.name,string);
125	if(params[0]>1)
126	{
127		map_regions[params[1]].window_addr_physical = params[2];
128	}
129	if(params[0]>2)
130	{
131		map_regions[params[1]].map_info.size = params[3];
132	}
133	if(params[0]>3)
134	{
135		map_regions[params[1]].map_info.bankwidth = params[4];
136	}
137	if(params[0]>4)
138	{
139		map_regions[params[1]].altbankwidth = params[5];
140	}
141	return 1;
142}
143
144static int __init MTD_New_Partition(char *line)
145{
146	char	string[MAX_NAME_SIZE];
147	int	params[4];
148	get_options (get_string_option(string,sizeof(string),line),4,params);
149	if(params[0]<3)
150	{
151		printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition "
152			" name,region-number,size,offset\n");
153		return 1;
154	}
155	if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
156	{
157		printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n",
158			params[1],MAX_NUM_REGIONS-1);
159		return 1;
160	}
161	if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS)
162	{
163		printk(MTD_FORTUNET_PK "Out of space for partition in this region\n");
164		return 1;
165	}
166	map_regions[params[1]].parts[map_regions_parts[params[1]]].name =
167		map_regions[params[1]].	parts_name[map_regions_parts[params[1]]];
168	strcpy(map_regions[params[1]].parts[map_regions_parts[params[1]]].name,string);
169	map_regions[params[1]].parts[map_regions_parts[params[1]]].size =
170		params[2];
171	map_regions[params[1]].parts[map_regions_parts[params[1]]].offset =
172		params[3];
173	map_regions[params[1]].parts[map_regions_parts[params[1]]].mask_flags = 0;
174	map_regions_parts[params[1]]++;
175	return 1;
176}
177
178__setup("MTD_Region=", MTD_New_Region);
179__setup("MTD_Partition=", MTD_New_Partition);
180
181/* Backwards-spelling-compatibility */
182__setup("MTD_Partion=", MTD_New_Partition);
183
184static int __init init_fortunet(void)
185{
186	int	ix,iy;
187	for(iy=ix=0;ix<MAX_NUM_REGIONS;ix++)
188	{
189		if(map_regions_parts[ix]&&(!map_regions_set[ix]))
190		{
191			printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n",
192				ix);
193			memset(&map_regions[ix],0,sizeof(map_regions[ix]));
194			memcpy(&map_regions[ix].map_info,&default_map,
195				sizeof(map_regions[ix].map_info));
196			map_regions_set[ix] = 1;
197			map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY;
198			map_regions[ix].altbankwidth = 2;
199			map_regions[ix].mymtd = NULL;
200			map_regions[ix].map_info.name = map_regions[ix].map_name;
201			strcpy(map_regions[ix].map_info.name,"FORTUNET");
202		}
203		if(map_regions_set[ix])
204		{
205			iy++;
206			printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically "
207				" address %x size %x\n",
208				map_regions[ix].map_info.name,
209				map_regions[ix].window_addr_physical,
210				map_regions[ix].map_info.size);
211
212			map_regions[ix].map_info.phys =	map_regions[ix].window_addr_physical,
213
214			map_regions[ix].map_info.virt =
215				ioremap_nocache(
216				map_regions[ix].window_addr_physical,
217				map_regions[ix].map_info.size);
218			if(!map_regions[ix].map_info.virt)
219			{
220				int j = 0;
221				printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n",
222					map_regions[ix].map_info.name);
223				for (j = 0 ; j < ix; j++)
224					iounmap(map_regions[j].map_info.virt);
225				return -ENXIO;
226			}
227			simple_map_init(&map_regions[ix].map_info);
228
229			printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n",
230				map_regions[ix].map_info.name,
231				map_regions[ix].map_info.virt);
232			map_regions[ix].mymtd = do_map_probe("cfi_probe",
233				&map_regions[ix].map_info);
234			if((!map_regions[ix].mymtd)&&(
235				map_regions[ix].altbankwidth!=map_regions[ix].map_info.bankwidth))
236			{
237				printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate bankwidth "
238					"for %s flash.\n",
239					map_regions[ix].map_info.name);
240				map_regions[ix].map_info.bankwidth =
241					map_regions[ix].altbankwidth;
242				map_regions[ix].mymtd = do_map_probe("cfi_probe",
243					&map_regions[ix].map_info);
244			}
245			map_regions[ix].mymtd->owner = THIS_MODULE;
246			mtd_device_register(map_regions[ix].mymtd,
247					    map_regions[ix].parts,
248					    map_regions_parts[ix]);
249		}
250	}
251	if(iy)
252		return 0;
253	return -ENXIO;
254}
255
256static void __exit cleanup_fortunet(void)
257{
258	int	ix;
259	for(ix=0;ix<MAX_NUM_REGIONS;ix++)
260	{
261		if(map_regions_set[ix])
262		{
263			if( map_regions[ix].mymtd )
264			{
265				mtd_device_unregister(map_regions[ix].mymtd);
266				map_destroy( map_regions[ix].mymtd );
267			}
268			iounmap((void *)map_regions[ix].map_info.virt);
269		}
270	}
271}
272
273module_init(init_fortunet);
274module_exit(cleanup_fortunet);
275
276MODULE_AUTHOR("FortuNet, Inc.");
277MODULE_DESCRIPTION("MTD map driver for FortuNet boards");