1
2
3#include <linux/kernel.h>
4#include <linux/module.h>
5#include <asm/uaccess.h>
6#include <linux/types.h>
7#include <linux/init.h>
8#include <linux/ptrace.h>
9#include <linux/slab.h>
10#include <linux/string.h>
11#include <linux/timer.h>
12#include <linux/major.h>
13#include <linux/fs.h>
14#include <linux/ioctl.h>
15#include <asm/io.h>
16#include <asm/system.h>
17#include <linux/pci.h>
18
19#include <linux/mtd/mtd.h>
20#include <linux/mtd/pmc551.h>
21#include <linux/mtd/compatmac.h>
22
23static struct mtd_info *pmc551list;
24
25static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
26{
27	struct mypriv *priv = mtd->priv;
28	u32 soff_hi, soff_lo;	/* start address offset hi/lo */
29	u32 eoff_hi, eoff_lo;	/* end address offset hi/lo */
30	unsigned long end;
31	u_char *ptr;
32	size_t retlen;
33
34#ifdef CONFIG_MTD_PMC551_DEBUG
35	printk(KERN_DEBUG "pmc551_erase(pos:%ld, len:%ld)\n", (long)instr->addr,
36		(long)instr->len);
37#endif
38
39	end = instr->addr + instr->len - 1;
40
41	/* Is it past the end? */
42	if (end > mtd->size) {
43#ifdef CONFIG_MTD_PMC551_DEBUG
44		printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n",
45			(long)end, (long)mtd->size);
46#endif
47		return -EINVAL;
48	}
49
50	eoff_hi = end & ~(priv->asize - 1);
51	soff_hi = instr->addr & ~(priv->asize - 1);
52	eoff_lo = end & (priv->asize - 1);
53	soff_lo = instr->addr & (priv->asize - 1);
54
55	pmc551_point(mtd, instr->addr, instr->len, &retlen, &ptr);
56
57	if (soff_hi == eoff_hi || mtd->size == priv->asize) {
58		/* The whole thing fits within one access, so just one shot
59		   will do it. */
60		memset(ptr, 0xff, instr->len);
61	} else {
62		/* We have to do multiple writes to get all the data
63		   written. */
64		while (soff_hi != eoff_hi) {
65#ifdef CONFIG_MTD_PMC551_DEBUG
66			printk(KERN_DEBUG "pmc551_erase() soff_hi: %ld, "
67				"eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
68#endif
69			memset(ptr, 0xff, priv->asize);
70			if (soff_hi + priv->asize >= mtd->size) {
71				goto out;
72			}
73			soff_hi += priv->asize;
74			pmc551_point(mtd, (priv->base_map0 | soff_hi),
75				     priv->asize, &retlen, &ptr);
76		}
77		memset(ptr, 0xff, eoff_lo);
78	}
79
80      out:
81	instr->state = MTD_ERASE_DONE;
82#ifdef CONFIG_MTD_PMC551_DEBUG
83	printk(KERN_DEBUG "pmc551_erase() done\n");
84#endif
85
86	mtd_erase_callback(instr);
87	return 0;
88}
89
90static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
91			size_t * retlen, u_char ** mtdbuf)
92{
93	struct mypriv *priv = mtd->priv;
94	u32 soff_hi;
95	u32 soff_lo;
96
97#ifdef CONFIG_MTD_PMC551_DEBUG
98	printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len);
99#endif
100
101	if (from + len > mtd->size) {
102#ifdef CONFIG_MTD_PMC551_DEBUG
103		printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n",
104			(long)from + len, (long)mtd->size);
105#endif
106		return -EINVAL;
107	}
108
109	soff_hi = from & ~(priv->asize - 1);
110	soff_lo = from & (priv->asize - 1);
111
112	/* Cheap hack optimization */
113	if (priv->curr_map0 != from) {
114		pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0,
115					(priv->base_map0 | soff_hi));
116		priv->curr_map0 = soff_hi;
117	}
118
119	*mtdbuf = priv->start + soff_lo;
120	*retlen = len;
121	return 0;
122}
123
124static void pmc551_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
125			   size_t len)
126{
127#ifdef CONFIG_MTD_PMC551_DEBUG
128	printk(KERN_DEBUG "pmc551_unpoint()\n");
129#endif
130}
131
132static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
133			size_t * retlen, u_char * buf)
134{
135	struct mypriv *priv = mtd->priv;
136	u32 soff_hi, soff_lo;	/* start address offset hi/lo */
137	u32 eoff_hi, eoff_lo;	/* end address offset hi/lo */
138	unsigned long end;
139	u_char *ptr;
140	u_char *copyto = buf;
141
142#ifdef CONFIG_MTD_PMC551_DEBUG
143	printk(KERN_DEBUG "pmc551_read(pos:%ld, len:%ld) asize: %ld\n",
144		(long)from, (long)len, (long)priv->asize);
145#endif
146
147	end = from + len - 1;
148
149	/* Is it past the end? */
150	if (end > mtd->size) {
151#ifdef CONFIG_MTD_PMC551_DEBUG
152		printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n",
153			(long)end, (long)mtd->size);
154#endif
155		return -EINVAL;
156	}
157
158	soff_hi = from & ~(priv->asize - 1);
159	eoff_hi = end & ~(priv->asize - 1);
160	soff_lo = from & (priv->asize - 1);
161	eoff_lo = end & (priv->asize - 1);
162
163	pmc551_point(mtd, from, len, retlen, &ptr);
164
165	if (soff_hi == eoff_hi) {
166		/* The whole thing fits within one access, so just one shot
167		   will do it. */
168		memcpy(copyto, ptr, len);
169		copyto += len;
170	} else {
171		/* We have to do multiple writes to get all the data
172		   written. */
173		while (soff_hi != eoff_hi) {
174#ifdef CONFIG_MTD_PMC551_DEBUG
175			printk(KERN_DEBUG "pmc551_read() soff_hi: %ld, "
176				"eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
177#endif
178			memcpy(copyto, ptr, priv->asize);
179			copyto += priv->asize;
180			if (soff_hi + priv->asize >= mtd->size) {
181				goto out;
182			}
183			soff_hi += priv->asize;
184			pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
185		}
186		memcpy(copyto, ptr, eoff_lo);
187		copyto += eoff_lo;
188	}
189
190      out:
191#ifdef CONFIG_MTD_PMC551_DEBUG
192	printk(KERN_DEBUG "pmc551_read() done\n");
193#endif
194	*retlen = copyto - buf;
195	return 0;
196}
197
198static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
199			size_t * retlen, const u_char * buf)
200{
201	struct mypriv *priv = mtd->priv;
202	u32 soff_hi, soff_lo;	/* start address offset hi/lo */
203	u32 eoff_hi, eoff_lo;	/* end address offset hi/lo */
204	unsigned long end;
205	u_char *ptr;
206	const u_char *copyfrom = buf;
207
208#ifdef CONFIG_MTD_PMC551_DEBUG
209	printk(KERN_DEBUG "pmc551_write(pos:%ld, len:%ld) asize:%ld\n",
210		(long)to, (long)len, (long)priv->asize);
211#endif
212
213	end = to + len - 1;
214	/* Is it past the end?  or did the u32 wrap? */
215	if (end > mtd->size) {
216#ifdef CONFIG_MTD_PMC551_DEBUG
217		printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, "
218			"size: %ld, to: %ld)\n", (long)end, (long)mtd->size,
219			(long)to);
220#endif
221		return -EINVAL;
222	}
223
224	soff_hi = to & ~(priv->asize - 1);
225	eoff_hi = end & ~(priv->asize - 1);
226	soff_lo = to & (priv->asize - 1);
227	eoff_lo = end & (priv->asize - 1);
228
229	pmc551_point(mtd, to, len, retlen, &ptr);
230
231	if (soff_hi == eoff_hi) {
232		/* The whole thing fits within one access, so just one shot
233		   will do it. */
234		memcpy(ptr, copyfrom, len);
235		copyfrom += len;
236	} else {
237		/* We have to do multiple writes to get all the data
238		   written. */
239		while (soff_hi != eoff_hi) {
240#ifdef CONFIG_MTD_PMC551_DEBUG
241			printk(KERN_DEBUG "pmc551_write() soff_hi: %ld, "
242				"eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
243#endif
244			memcpy(ptr, copyfrom, priv->asize);
245			copyfrom += priv->asize;
246			if (soff_hi >= mtd->size) {
247				goto out;
248			}
249			soff_hi += priv->asize;
250			pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
251		}
252		memcpy(ptr, copyfrom, eoff_lo);
253		copyfrom += eoff_lo;
254	}
255
256      out:
257#ifdef CONFIG_MTD_PMC551_DEBUG
258	printk(KERN_DEBUG "pmc551_write() done\n");
259#endif
260	*retlen = copyfrom - buf;
261	return 0;
262}
263
264static u32 fixup_pmc551(struct pci_dev *dev)
265{
266#ifdef CONFIG_MTD_PMC551_BUGFIX
267	u32 dram_data;
268#endif
269	u32 size, dcmd, cfg, dtmp;
270	u16 cmd, tmp, i;
271	u8 bcmd, counter;
272
273	/* Sanity Check */
274	if (!dev) {
275		return -ENODEV;
276	}
277
278	counter = 0;
279	/* unlock registers */
280	pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, 0xA5);
281	/* read in old data */
282	pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd);
283	/* bang the reset line up and down for a few */
284	for (i = 0; i < 10; i++) {
285		counter = 0;
286		bcmd &= ~0x80;
287		while (counter++ < 100) {
288			pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
289		}
290		counter = 0;
291		bcmd |= 0x80;
292		while (counter++ < 100) {
293			pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
294		}
295	}
296	bcmd |= (0x40 | 0x20);
297	pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
298
299	/*
300	 * Take care and turn off the memory on the device while we
301	 * tweak the configurations
302	 */
303	pci_read_config_word(dev, PCI_COMMAND, &cmd);
304	tmp = cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
305	pci_write_config_word(dev, PCI_COMMAND, tmp);
306
307	/*
308	 * Disable existing aperture before probing memory size
309	 */
310	pci_read_config_dword(dev, PMC551_PCI_MEM_MAP0, &dcmd);
311	dtmp = (dcmd | PMC551_PCI_MEM_MAP_ENABLE | PMC551_PCI_MEM_MAP_REG_EN);
312	pci_write_config_dword(dev, PMC551_PCI_MEM_MAP0, dtmp);
313	/*
314	 * Grab old BAR0 config so that we can figure out memory size
315	 * This is another bit of kludge going on.  The reason for the
316	 * redundancy is I am hoping to retain the original configuration
317	 * previously assigned to the card by the BIOS or some previous
318	 * fixup routine in the kernel.  So we read the old config into cfg,
319	 * then write all 1's to the memory space, read back the result into
320	 * "size", and then write back all the old config.
321	 */
322	pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &cfg);
323#ifndef CONFIG_MTD_PMC551_BUGFIX
324	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, ~0);
325	pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &size);
326	size = (size & PCI_BASE_ADDRESS_MEM_MASK);
327	size &= ~(size - 1);
328	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, cfg);
329#else
330	/*
331	 * Get the size of the memory by reading all the DRAM size values
332	 * and adding them up.
333	 *
334	 * KLUDGE ALERT: the boards we are using have invalid column and
335	 * row mux values.  We fix them here, but this will break other
336	 * memory configurations.
337	 */
338	pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dram_data);
339	size = PMC551_DRAM_BLK_GET_SIZE(dram_data);
340	dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
341	dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
342	pci_write_config_dword(dev, PMC551_DRAM_BLK0, dram_data);
343
344	pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dram_data);
345	size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
346	dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
347	dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
348	pci_write_config_dword(dev, PMC551_DRAM_BLK1, dram_data);
349
350	pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dram_data);
351	size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
352	dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
353	dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
354	pci_write_config_dword(dev, PMC551_DRAM_BLK2, dram_data);
355
356	pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dram_data);
357	size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
358	dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
359	dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
360	pci_write_config_dword(dev, PMC551_DRAM_BLK3, dram_data);
361
362	/*
363	 * Oops .. something went wrong
364	 */
365	if ((size &= PCI_BASE_ADDRESS_MEM_MASK) == 0) {
366		return -ENODEV;
367	}
368#endif				/* CONFIG_MTD_PMC551_BUGFIX */
369
370	if ((cfg & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) {
371		return -ENODEV;
372	}
373
374	/*
375	 * Precharge Dram
376	 */
377	pci_write_config_word(dev, PMC551_SDRAM_MA, 0x0400);
378	pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x00bf);
379
380	do {
381		pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd);
382		if (counter++ > 100)
383			break;
384	} while ((PCI_COMMAND_IO) & cmd);
385
386	/*
387	 * Turn on auto refresh
388	 * The loop is taken directly from Ramix's example code.  I assume that
389	 * this must be held high for some duration of time, but I can find no
390	 * documentation refrencing the reasons why.
391	 */
392	for (i = 1; i <= 8; i++) {
393		pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x0df);
394
395		counter = 0;
396		do {
397			pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd);
398			if (counter++ > 100)
399				break;
400		} while ((PCI_COMMAND_IO) & cmd);
401	}
402
403	pci_write_config_word(dev, PMC551_SDRAM_MA, 0x0020);
404	pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x0ff);
405
406	counter = 0;
407	do {
408		pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd);
409		if (counter++ > 100)
410			break;
411	} while ((PCI_COMMAND_IO) & cmd);
412
413	pci_read_config_dword(dev, PMC551_DRAM_CFG, &dcmd);
414	dcmd |= 0x02000000;
415	pci_write_config_dword(dev, PMC551_DRAM_CFG, dcmd);
416
417	/*
418	 * Check to make certain fast back-to-back, if not
419	 * then set it so
420	 */
421	pci_read_config_word(dev, PCI_STATUS, &cmd);
422	if ((cmd & PCI_COMMAND_FAST_BACK) == 0) {
423		cmd |= PCI_COMMAND_FAST_BACK;
424		pci_write_config_word(dev, PCI_STATUS, cmd);
425	}
426
427	/*
428	 * Check to make certain the DEVSEL is set correctly, this device
429	 * has a tendancy to assert DEVSEL and TRDY when a write is performed
430	 * to the memory when memory is read-only
431	 */
432	if ((cmd & PCI_STATUS_DEVSEL_MASK) != 0x0) {
433		cmd &= ~PCI_STATUS_DEVSEL_MASK;
434		pci_write_config_word(dev, PCI_STATUS, cmd);
435	}
436	/*
437	 * Set to be prefetchable and put everything back based on old cfg.
438	 * it's possible that the reset of the V370PDC nuked the original
439	 * setup
440	 */
441	/*
442	   cfg |= PCI_BASE_ADDRESS_MEM_PREFETCH;
443	   pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg );
444	 */
445
446	/*
447	 * Turn PCI memory and I/O bus access back on
448	 */
449	pci_write_config_word(dev, PCI_COMMAND,
450			      PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
451#ifdef CONFIG_MTD_PMC551_DEBUG
452	/*
453	 * Some screen fun
454	 */
455	printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at "
456		"0x%llx\n", (size < 1024) ? size : (size < 1048576) ?
457		size >> 10 : size >> 20,
458		(size < 1024) ? 'B' : (size < 1048576) ? 'K' : 'M', size,
459		((dcmd & (0x1 << 3)) == 0) ? "non-" : "",
460		(unsigned long long)pci_resource_start(dev, 0));
461
462	/*
463	 * Check to see the state of the memory
464	 */
465	pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dcmd);
466	printk(KERN_DEBUG "pmc551: DRAM_BLK0 Flags: %s,%s\n"
467		"pmc551: DRAM_BLK0 Size: %d at %d\n"
468		"pmc551: DRAM_BLK0 Row MUX: %d, Col MUX: %d\n",
469		(((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
470		(((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
471		PMC551_DRAM_BLK_GET_SIZE(dcmd),
472		((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
473		((dcmd >> 9) & 0xF));
474
475	pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dcmd);
476	printk(KERN_DEBUG "pmc551: DRAM_BLK1 Flags: %s,%s\n"
477		"pmc551: DRAM_BLK1 Size: %d at %d\n"
478		"pmc551: DRAM_BLK1 Row MUX: %d, Col MUX: %d\n",
479		(((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
480		(((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
481		PMC551_DRAM_BLK_GET_SIZE(dcmd),
482		((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
483		((dcmd >> 9) & 0xF));
484
485	pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dcmd);
486	printk(KERN_DEBUG "pmc551: DRAM_BLK2 Flags: %s,%s\n"
487		"pmc551: DRAM_BLK2 Size: %d at %d\n"
488		"pmc551: DRAM_BLK2 Row MUX: %d, Col MUX: %d\n",
489		(((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
490		(((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
491		PMC551_DRAM_BLK_GET_SIZE(dcmd),
492		((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
493		((dcmd >> 9) & 0xF));
494
495	pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dcmd);
496	printk(KERN_DEBUG "pmc551: DRAM_BLK3 Flags: %s,%s\n"
497		"pmc551: DRAM_BLK3 Size: %d at %d\n"
498		"pmc551: DRAM_BLK3 Row MUX: %d, Col MUX: %d\n",
499		(((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
500		(((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
501		PMC551_DRAM_BLK_GET_SIZE(dcmd),
502		((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
503		((dcmd >> 9) & 0xF));
504
505	pci_read_config_word(dev, PCI_COMMAND, &cmd);
506	printk(KERN_DEBUG "pmc551: Memory Access %s\n",
507		(((0x1 << 1) & cmd) == 0) ? "off" : "on");
508	printk(KERN_DEBUG "pmc551: I/O Access %s\n",
509		(((0x1 << 0) & cmd) == 0) ? "off" : "on");
510
511	pci_read_config_word(dev, PCI_STATUS, &cmd);
512	printk(KERN_DEBUG "pmc551: Devsel %s\n",
513		((PCI_STATUS_DEVSEL_MASK & cmd) == 0x000) ? "Fast" :
514		((PCI_STATUS_DEVSEL_MASK & cmd) == 0x200) ? "Medium" :
515		((PCI_STATUS_DEVSEL_MASK & cmd) == 0x400) ? "Slow" : "Invalid");
516
517	printk(KERN_DEBUG "pmc551: %sFast Back-to-Back\n",
518		((PCI_COMMAND_FAST_BACK & cmd) == 0) ? "Not " : "");
519
520	pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd);
521	printk(KERN_DEBUG "pmc551: EEPROM is under %s control\n"
522		"pmc551: System Control Register is %slocked to PCI access\n"
523		"pmc551: System Control Register is %slocked to EEPROM access\n",
524		(bcmd & 0x1) ? "software" : "hardware",
525		(bcmd & 0x20) ? "" : "un", (bcmd & 0x40) ? "" : "un");
526#endif
527	return size;
528}
529
530/*
531 * Kernel version specific module stuffages
532 */
533
534MODULE_LICENSE("GPL");
535MODULE_AUTHOR("Mark Ferrell <mferrell@mvista.com>");
536MODULE_DESCRIPTION(PMC551_VERSION);
537
538/*
539 * Stuff these outside the ifdef so as to not bust compiled in driver support
540 */
541static int msize = 0;
542#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE)
543static int asize = CONFIG_MTD_PMC551_APERTURE_SIZE;
544#else
545static int asize = 0;
546#endif
547
548module_param(msize, int, 0);
549MODULE_PARM_DESC(msize, "memory size in Megabytes [1 - 1024]");
550module_param(asize, int, 0);
551MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]");
552
553/*
554 * PMC551 Card Initialization
555 */
556static int __init init_pmc551(void)
557{
558	struct pci_dev *PCI_Device = NULL;
559	struct mypriv *priv;
560	int count, found = 0;
561	struct mtd_info *mtd;
562	u32 length = 0;
563
564	if (msize) {
565		msize = (1 << (ffs(msize) - 1)) << 20;
566		if (msize > (1 << 30)) {
567			printk(KERN_NOTICE "pmc551: Invalid memory size [%d]\n",
568				msize);
569			return -EINVAL;
570		}
571	}
572
573	if (asize) {
574		asize = (1 << (ffs(asize) - 1)) << 20;
575		if (asize > (1 << 30)) {
576			printk(KERN_NOTICE "pmc551: Invalid aperture size "
577				"[%d]\n", asize);
578			return -EINVAL;
579		}
580	}
581
582	printk(KERN_INFO PMC551_VERSION);
583
584	/*
585	 * PCU-bus chipset probe.
586	 */
587	for (count = 0; count < MAX_MTD_DEVICES; count++) {
588
589		if ((PCI_Device = pci_get_device(PCI_VENDOR_ID_V3_SEMI,
590						  PCI_DEVICE_ID_V3_SEMI_V370PDC,
591						  PCI_Device)) == NULL) {
592			break;
593		}
594
595		printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%llx\n",
596			(unsigned long long)pci_resource_start(PCI_Device, 0));
597
598		/*
599		 * The PMC551 device acts VERY weird if you don't init it
600		 * first.  i.e. it will not correctly report devsel.  If for
601		 * some reason the sdram is in a wrote-protected state the
602		 * device will DEVSEL when it is written to causing problems
603		 * with the oldproc.c driver in
604		 * some kernels (2.2.*)
605		 */
606		if ((length = fixup_pmc551(PCI_Device)) <= 0) {
607			printk(KERN_NOTICE "pmc551: Cannot init SDRAM\n");
608			break;
609		}
610
611		/*
612		 * This is needed until the driver is capable of reading the
613		 * onboard I2C SROM to discover the "real" memory size.
614		 */
615		if (msize) {
616			length = msize;
617			printk(KERN_NOTICE "pmc551: Using specified memory "
618				"size 0x%x\n", length);
619		} else {
620			msize = length;
621		}
622
623		mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
624		if (!mtd) {
625			printk(KERN_NOTICE "pmc551: Cannot allocate new MTD "
626				"device.\n");
627			break;
628		}
629
630		priv = kzalloc(sizeof(struct mypriv), GFP_KERNEL);
631		if (!priv) {
632			printk(KERN_NOTICE "pmc551: Cannot allocate new MTD "
633				"device.\n");
634			kfree(mtd);
635			break;
636		}
637		mtd->priv = priv;
638		priv->dev = PCI_Device;
639
640		if (asize > length) {
641			printk(KERN_NOTICE "pmc551: reducing aperture size to "
642				"fit %dM\n", length >> 20);
643			priv->asize = asize = length;
644		} else if (asize == 0 || asize == length) {
645			printk(KERN_NOTICE "pmc551: Using existing aperture "
646				"size %dM\n", length >> 20);
647			priv->asize = asize = length;
648		} else {
649			printk(KERN_NOTICE "pmc551: Using specified aperture "
650				"size %dM\n", asize >> 20);
651			priv->asize = asize;
652		}
653		priv->start = pci_iomap(PCI_Device, 0, priv->asize);
654
655		if (!priv->start) {
656			printk(KERN_NOTICE "pmc551: Unable to map IO space\n");
657			kfree(mtd->priv);
658			kfree(mtd);
659			break;
660		}
661#ifdef CONFIG_MTD_PMC551_DEBUG
662		printk(KERN_DEBUG "pmc551: setting aperture to %d\n",
663			ffs(priv->asize >> 20) - 1);
664#endif
665
666		priv->base_map0 = (PMC551_PCI_MEM_MAP_REG_EN
667				   | PMC551_PCI_MEM_MAP_ENABLE
668				   | (ffs(priv->asize >> 20) - 1) << 4);
669		priv->curr_map0 = priv->base_map0;
670		pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0,
671					priv->curr_map0);
672
673#ifdef CONFIG_MTD_PMC551_DEBUG
674		printk(KERN_DEBUG "pmc551: aperture set to %d\n",
675			(priv->base_map0 & 0xF0) >> 4);
676#endif
677
678		mtd->size = msize;
679		mtd->flags = MTD_CAP_RAM;
680		mtd->erase = pmc551_erase;
681		mtd->read = pmc551_read;
682		mtd->write = pmc551_write;
683		mtd->point = pmc551_point;
684		mtd->unpoint = pmc551_unpoint;
685		mtd->type = MTD_RAM;
686		mtd->name = "PMC551 RAM board";
687		mtd->erasesize = 0x10000;
688		mtd->writesize = 1;
689		mtd->owner = THIS_MODULE;
690
691		if (add_mtd_device(mtd)) {
692			printk(KERN_NOTICE "pmc551: Failed to register new "
693				"device\n");
694			pci_iounmap(PCI_Device, priv->start);
695			kfree(mtd->priv);
696			kfree(mtd);
697			break;
698		}
699
700		/* Keep a reference as the add_mtd_device worked */
701		pci_dev_get(PCI_Device);
702
703		printk(KERN_NOTICE "Registered pmc551 memory device.\n");
704		printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n",
705			priv->asize >> 20,
706			priv->start, priv->start + priv->asize);
707		printk(KERN_NOTICE "Total memory is %d%c\n",
708			(length < 1024) ? length :
709			(length < 1048576) ? length >> 10 : length >> 20,
710			(length < 1024) ? 'B' : (length < 1048576) ? 'K' : 'M');
711		priv->nextpmc551 = pmc551list;
712		pmc551list = mtd;
713		found++;
714	}
715
716	/* Exited early, reference left over */
717	if (PCI_Device)
718		pci_dev_put(PCI_Device);
719
720	if (!pmc551list) {
721		printk(KERN_NOTICE "pmc551: not detected\n");
722		return -ENODEV;
723	} else {
724		printk(KERN_NOTICE "pmc551: %d pmc551 devices loaded\n", found);
725		return 0;
726	}
727}
728
729/*
730 * PMC551 Card Cleanup
731 */
732static void __exit cleanup_pmc551(void)
733{
734	int found = 0;
735	struct mtd_info *mtd;
736	struct mypriv *priv;
737
738	while ((mtd = pmc551list)) {
739		priv = mtd->priv;
740		pmc551list = priv->nextpmc551;
741
742		if (priv->start) {
743			printk(KERN_DEBUG "pmc551: unmapping %dM starting at "
744				"0x%p\n", priv->asize >> 20, priv->start);
745			pci_iounmap(priv->dev, priv->start);
746		}
747		pci_dev_put(priv->dev);
748
749		kfree(mtd->priv);
750		del_mtd_device(mtd);
751		kfree(mtd);
752		found++;
753	}
754
755	printk(KERN_NOTICE "pmc551: %d pmc551 devices unloaded\n", found);
756}
757
758module_init(init_pmc551);
759module_exit(cleanup_pmc551);
760