aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices/pmc551.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/devices/pmc551.c')
-rw-r--r--drivers/mtd/devices/pmc551.c1154
1 files changed, 593 insertions, 561 deletions
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index 2c0149708739..354e1657cc26 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -4,82 +4,82 @@
4 * PMC551 PCI Mezzanine Ram Device 4 * PMC551 PCI Mezzanine Ram Device
5 * 5 *
6 * Author: 6 * Author:
7 * Mark Ferrell <mferrell@mvista.com> 7 * Mark Ferrell <mferrell@mvista.com>
8 * Copyright 1999,2000 Nortel Networks 8 * Copyright 1999,2000 Nortel Networks
9 * 9 *
10 * License: 10 * License:
11 * As part of this driver was derived from the slram.c driver it 11 * As part of this driver was derived from the slram.c driver it
12 * falls under the same license, which is GNU General Public 12 * falls under the same license, which is GNU General Public
13 * License v2 13 * License v2
14 * 14 *
15 * Description: 15 * Description:
16 * This driver is intended to support the PMC551 PCI Ram device 16 * This driver is intended to support the PMC551 PCI Ram device
17 * from Ramix Inc. The PMC551 is a PMC Mezzanine module for 17 * from Ramix Inc. The PMC551 is a PMC Mezzanine module for
18 * cPCI embedded systems. The device contains a single SROM 18 * cPCI embedded systems. The device contains a single SROM
19 * that initially programs the V370PDC chipset onboard the 19 * that initially programs the V370PDC chipset onboard the
20 * device, and various banks of DRAM/SDRAM onboard. This driver 20 * device, and various banks of DRAM/SDRAM onboard. This driver
21 * implements this PCI Ram device as an MTD (Memory Technology 21 * implements this PCI Ram device as an MTD (Memory Technology
22 * Device) so that it can be used to hold a file system, or for 22 * Device) so that it can be used to hold a file system, or for
23 * added swap space in embedded systems. Since the memory on 23 * added swap space in embedded systems. Since the memory on
24 * this board isn't as fast as main memory we do not try to hook 24 * this board isn't as fast as main memory we do not try to hook
25 * it into main memory as that would simply reduce performance 25 * it into main memory as that would simply reduce performance
26 * on the system. Using it as a block device allows us to use 26 * on the system. Using it as a block device allows us to use
27 * it as high speed swap or for a high speed disk device of some 27 * it as high speed swap or for a high speed disk device of some
28 * sort. Which becomes very useful on diskless systems in the 28 * sort. Which becomes very useful on diskless systems in the
29 * embedded market I might add. 29 * embedded market I might add.
30 * 30 *
31 * Notes: 31 * Notes:
32 * Due to what I assume is more buggy SROM, the 64M PMC551 I 32 * Due to what I assume is more buggy SROM, the 64M PMC551 I
33 * have available claims that all 4 of it's DRAM banks have 64M 33 * have available claims that all 4 of it's DRAM banks have 64M
34 * of ram configured (making a grand total of 256M onboard). 34 * of ram configured (making a grand total of 256M onboard).
35 * This is slightly annoying since the BAR0 size reflects the 35 * This is slightly annoying since the BAR0 size reflects the
36 * aperture size, not the dram size, and the V370PDC supplies no 36 * aperture size, not the dram size, and the V370PDC supplies no
37 * other method for memory size discovery. This problem is 37 * other method for memory size discovery. This problem is
38 * mostly only relevant when compiled as a module, as the 38 * mostly only relevant when compiled as a module, as the
39 * unloading of the module with an aperture size smaller then 39 * unloading of the module with an aperture size smaller then
40 * the ram will cause the driver to detect the onboard memory 40 * the ram will cause the driver to detect the onboard memory
41 * size to be equal to the aperture size when the module is 41 * size to be equal to the aperture size when the module is
42 * reloaded. Soooo, to help, the module supports an msize 42 * reloaded. Soooo, to help, the module supports an msize
43 * option to allow the specification of the onboard memory, and 43 * option to allow the specification of the onboard memory, and
44 * an asize option, to allow the specification of the aperture 44 * an asize option, to allow the specification of the aperture
45 * size. The aperture must be equal to or less then the memory 45 * size. The aperture must be equal to or less then the memory
46 * size, the driver will correct this if you screw it up. This 46 * size, the driver will correct this if you screw it up. This
47 * problem is not relevant for compiled in drivers as compiled 47 * problem is not relevant for compiled in drivers as compiled
48 * in drivers only init once. 48 * in drivers only init once.
49 * 49 *
50 * Credits: 50 * Credits:
51 * Saeed Karamooz <saeed@ramix.com> of Ramix INC. for the 51 * Saeed Karamooz <saeed@ramix.com> of Ramix INC. for the
52 * initial example code of how to initialize this device and for 52 * initial example code of how to initialize this device and for
53 * help with questions I had concerning operation of the device. 53 * help with questions I had concerning operation of the device.
54 * 54 *
55 * Most of the MTD code for this driver was originally written 55 * Most of the MTD code for this driver was originally written
56 * for the slram.o module in the MTD drivers package which 56 * for the slram.o module in the MTD drivers package which
57 * allows the mapping of system memory into an MTD device. 57 * allows the mapping of system memory into an MTD device.
58 * Since the PMC551 memory module is accessed in the same 58 * Since the PMC551 memory module is accessed in the same
59 * fashion as system memory, the slram.c code became a very nice 59 * fashion as system memory, the slram.c code became a very nice
60 * fit to the needs of this driver. All we added was PCI 60 * fit to the needs of this driver. All we added was PCI
61 * detection/initialization to the driver and automatically figure 61 * detection/initialization to the driver and automatically figure
62 * out the size via the PCI detection.o, later changes by Corey 62 * out the size via the PCI detection.o, later changes by Corey
63 * Minyard set up the card to utilize a 1M sliding apature. 63 * Minyard set up the card to utilize a 1M sliding apature.
64 * 64 *
65 * Corey Minyard <minyard@nortelnetworks.com> 65 * Corey Minyard <minyard@nortelnetworks.com>
66 * * Modified driver to utilize a sliding aperture instead of 66 * * Modified driver to utilize a sliding aperture instead of
67 * mapping all memory into kernel space which turned out to 67 * mapping all memory into kernel space which turned out to
68 * be very wasteful. 68 * be very wasteful.
69 * * Located a bug in the SROM's initialization sequence that 69 * * Located a bug in the SROM's initialization sequence that
70 * made the memory unusable, added a fix to code to touch up 70 * made the memory unusable, added a fix to code to touch up
71 * the DRAM some. 71 * the DRAM some.
72 * 72 *
73 * Bugs/FIXME's: 73 * Bugs/FIXME's:
74 * * MUST fix the init function to not spin on a register 74 * * MUST fix the init function to not spin on a register
75 * waiting for it to set .. this does not safely handle busted 75 * waiting for it to set .. this does not safely handle busted
76 * devices that never reset the register correctly which will 76 * devices that never reset the register correctly which will
77 * cause the system to hang w/ a reboot being the only chance at 77 * cause the system to hang w/ a reboot being the only chance at
78 * recover. [sort of fixed, could be better] 78 * recover. [sort of fixed, could be better]
79 * * Add I2C handling of the SROM so we can read the SROM's information 79 * * Add I2C handling of the SROM so we can read the SROM's information
80 * about the aperture size. This should always accurately reflect the 80 * about the aperture size. This should always accurately reflect the
81 * onboard memory size. 81 * onboard memory size.
82 * * Comb the init routine. It's still a bit cludgy on a few things. 82 * * Comb the init routine. It's still a bit cludgy on a few things.
83 */ 83 */
84 84
85#include <linux/kernel.h> 85#include <linux/kernel.h>
@@ -105,74 +105,77 @@
105 105
106static struct mtd_info *pmc551list; 106static struct mtd_info *pmc551list;
107 107
108static int pmc551_erase (struct mtd_info *mtd, struct erase_info *instr) 108static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
109{ 109{
110 struct mypriv *priv = mtd->priv; 110 struct mypriv *priv = mtd->priv;
111 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 111 u32 soff_hi, soff_lo; /* start address offset hi/lo */
112 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 112 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
113 unsigned long end; 113 unsigned long end;
114 u_char *ptr; 114 u_char *ptr;
115 size_t retlen; 115 size_t retlen;
116 116
117#ifdef CONFIG_MTD_PMC551_DEBUG 117#ifdef CONFIG_MTD_PMC551_DEBUG
118 printk(KERN_DEBUG "pmc551_erase(pos:%ld, len:%ld)\n", (long)instr->addr, (long)instr->len); 118 printk(KERN_DEBUG "pmc551_erase(pos:%ld, len:%ld)\n", (long)instr->addr,
119 (long)instr->len);
119#endif 120#endif
120 121
121 end = instr->addr + instr->len - 1; 122 end = instr->addr + instr->len - 1;
122 123
123 /* Is it past the end? */ 124 /* Is it past the end? */
124 if ( end > mtd->size ) { 125 if (end > mtd->size) {
125#ifdef CONFIG_MTD_PMC551_DEBUG 126#ifdef CONFIG_MTD_PMC551_DEBUG
126 printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n", (long)end, (long)mtd->size); 127 printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n",
128 (long)end, (long)mtd->size);
127#endif 129#endif
128 return -EINVAL; 130 return -EINVAL;
129 } 131 }
130 132
131 eoff_hi = end & ~(priv->asize - 1); 133 eoff_hi = end & ~(priv->asize - 1);
132 soff_hi = instr->addr & ~(priv->asize - 1); 134 soff_hi = instr->addr & ~(priv->asize - 1);
133 eoff_lo = end & (priv->asize - 1); 135 eoff_lo = end & (priv->asize - 1);
134 soff_lo = instr->addr & (priv->asize - 1); 136 soff_lo = instr->addr & (priv->asize - 1);
135 137
136 pmc551_point (mtd, instr->addr, instr->len, &retlen, &ptr); 138 pmc551_point(mtd, instr->addr, instr->len, &retlen, &ptr);
137 139
138 if ( soff_hi == eoff_hi || mtd->size == priv->asize) { 140 if (soff_hi == eoff_hi || mtd->size == priv->asize) {
139 /* The whole thing fits within one access, so just one shot 141 /* The whole thing fits within one access, so just one shot
140 will do it. */ 142 will do it. */
141 memset(ptr, 0xff, instr->len); 143 memset(ptr, 0xff, instr->len);
142 } else { 144 } else {
143 /* We have to do multiple writes to get all the data 145 /* We have to do multiple writes to get all the data
144 written. */ 146 written. */
145 while (soff_hi != eoff_hi) { 147 while (soff_hi != eoff_hi) {
146#ifdef CONFIG_MTD_PMC551_DEBUG 148#ifdef CONFIG_MTD_PMC551_DEBUG
147 printk( KERN_DEBUG "pmc551_erase() soff_hi: %ld, eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 149 printk(KERN_DEBUG "pmc551_erase() soff_hi: %ld, "
150 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
148#endif 151#endif
149 memset(ptr, 0xff, priv->asize); 152 memset(ptr, 0xff, priv->asize);
150 if (soff_hi + priv->asize >= mtd->size) { 153 if (soff_hi + priv->asize >= mtd->size) {
151 goto out; 154 goto out;
152 } 155 }
153 soff_hi += priv->asize; 156 soff_hi += priv->asize;
154 pmc551_point (mtd,(priv->base_map0|soff_hi), 157 pmc551_point(mtd, (priv->base_map0 | soff_hi),
155 priv->asize, &retlen, &ptr); 158 priv->asize, &retlen, &ptr);
156 } 159 }
157 memset (ptr, 0xff, eoff_lo); 160 memset(ptr, 0xff, eoff_lo);
158 } 161 }
159 162
160out: 163 out:
161 instr->state = MTD_ERASE_DONE; 164 instr->state = MTD_ERASE_DONE;
162#ifdef CONFIG_MTD_PMC551_DEBUG 165#ifdef CONFIG_MTD_PMC551_DEBUG
163 printk(KERN_DEBUG "pmc551_erase() done\n"); 166 printk(KERN_DEBUG "pmc551_erase() done\n");
164#endif 167#endif
165 168
166 mtd_erase_callback(instr); 169 mtd_erase_callback(instr);
167 return 0; 170 return 0;
168} 171}
169 172
170 173static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
171static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) 174 size_t * retlen, u_char ** mtdbuf)
172{ 175{
173 struct mypriv *priv = mtd->priv; 176 struct mypriv *priv = mtd->priv;
174 u32 soff_hi; 177 u32 soff_hi;
175 u32 soff_lo; 178 u32 soff_lo;
176 179
177#ifdef CONFIG_MTD_PMC551_DEBUG 180#ifdef CONFIG_MTD_PMC551_DEBUG
178 printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len); 181 printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len);
@@ -180,18 +183,19 @@ static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *
180 183
181 if (from + len > mtd->size) { 184 if (from + len > mtd->size) {
182#ifdef CONFIG_MTD_PMC551_DEBUG 185#ifdef CONFIG_MTD_PMC551_DEBUG
183 printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n", (long)from+len, (long)mtd->size); 186 printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n",
187 (long)from + len, (long)mtd->size);
184#endif 188#endif
185 return -EINVAL; 189 return -EINVAL;
186 } 190 }
187 191
188 soff_hi = from & ~(priv->asize - 1); 192 soff_hi = from & ~(priv->asize - 1);
189 soff_lo = from & (priv->asize - 1); 193 soff_lo = from & (priv->asize - 1);
190 194
191 /* Cheap hack optimization */ 195 /* Cheap hack optimization */
192 if( priv->curr_map0 != from ) { 196 if (priv->curr_map0 != from) {
193 pci_write_config_dword ( priv->dev, PMC551_PCI_MEM_MAP0, 197 pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0,
194 (priv->base_map0 | soff_hi) ); 198 (priv->base_map0 | soff_hi));
195 priv->curr_map0 = soff_hi; 199 priv->curr_map0 = soff_hi;
196 } 200 }
197 201
@@ -200,137 +204,144 @@ static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *
200 return 0; 204 return 0;
201} 205}
202 206
203 207static void pmc551_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
204static void pmc551_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) 208 size_t len)
205{ 209{
206#ifdef CONFIG_MTD_PMC551_DEBUG 210#ifdef CONFIG_MTD_PMC551_DEBUG
207 printk(KERN_DEBUG "pmc551_unpoint()\n"); 211 printk(KERN_DEBUG "pmc551_unpoint()\n");
208#endif 212#endif
209} 213}
210 214
211 215static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
212static int pmc551_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) 216 size_t * retlen, u_char * buf)
213{ 217{
214 struct mypriv *priv = mtd->priv; 218 struct mypriv *priv = mtd->priv;
215 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 219 u32 soff_hi, soff_lo; /* start address offset hi/lo */
216 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 220 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
217 unsigned long end; 221 unsigned long end;
218 u_char *ptr; 222 u_char *ptr;
219 u_char *copyto = buf; 223 u_char *copyto = buf;
220 224
221#ifdef CONFIG_MTD_PMC551_DEBUG 225#ifdef CONFIG_MTD_PMC551_DEBUG
222 printk(KERN_DEBUG "pmc551_read(pos:%ld, len:%ld) asize: %ld\n", (long)from, (long)len, (long)priv->asize); 226 printk(KERN_DEBUG "pmc551_read(pos:%ld, len:%ld) asize: %ld\n",
227 (long)from, (long)len, (long)priv->asize);
223#endif 228#endif
224 229
225 end = from + len - 1; 230 end = from + len - 1;
226 231
227 /* Is it past the end? */ 232 /* Is it past the end? */
228 if (end > mtd->size) { 233 if (end > mtd->size) {
229#ifdef CONFIG_MTD_PMC551_DEBUG 234#ifdef CONFIG_MTD_PMC551_DEBUG
230 printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n", (long) end, (long)mtd->size); 235 printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n",
236 (long)end, (long)mtd->size);
231#endif 237#endif
232 return -EINVAL; 238 return -EINVAL;
233 } 239 }
234 240
235 soff_hi = from & ~(priv->asize - 1); 241 soff_hi = from & ~(priv->asize - 1);
236 eoff_hi = end & ~(priv->asize - 1); 242 eoff_hi = end & ~(priv->asize - 1);
237 soff_lo = from & (priv->asize - 1); 243 soff_lo = from & (priv->asize - 1);
238 eoff_lo = end & (priv->asize - 1); 244 eoff_lo = end & (priv->asize - 1);
239 245
240 pmc551_point (mtd, from, len, retlen, &ptr); 246 pmc551_point(mtd, from, len, retlen, &ptr);
241 247
242 if (soff_hi == eoff_hi) { 248 if (soff_hi == eoff_hi) {
243 /* The whole thing fits within one access, so just one shot 249 /* The whole thing fits within one access, so just one shot
244 will do it. */ 250 will do it. */
245 memcpy(copyto, ptr, len); 251 memcpy(copyto, ptr, len);
246 copyto += len; 252 copyto += len;
247 } else { 253 } else {
248 /* We have to do multiple writes to get all the data 254 /* We have to do multiple writes to get all the data
249 written. */ 255 written. */
250 while (soff_hi != eoff_hi) { 256 while (soff_hi != eoff_hi) {
251#ifdef CONFIG_MTD_PMC551_DEBUG 257#ifdef CONFIG_MTD_PMC551_DEBUG
252 printk( KERN_DEBUG "pmc551_read() soff_hi: %ld, eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 258 printk(KERN_DEBUG "pmc551_read() soff_hi: %ld, "
259 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
253#endif 260#endif
254 memcpy(copyto, ptr, priv->asize); 261 memcpy(copyto, ptr, priv->asize);
255 copyto += priv->asize; 262 copyto += priv->asize;
256 if (soff_hi + priv->asize >= mtd->size) { 263 if (soff_hi + priv->asize >= mtd->size) {
257 goto out; 264 goto out;
258 } 265 }
259 soff_hi += priv->asize; 266 soff_hi += priv->asize;
260 pmc551_point (mtd, soff_hi, priv->asize, retlen, &ptr); 267 pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
261 } 268 }
262 memcpy(copyto, ptr, eoff_lo); 269 memcpy(copyto, ptr, eoff_lo);
263 copyto += eoff_lo; 270 copyto += eoff_lo;
264 } 271 }
265 272
266out: 273 out:
267#ifdef CONFIG_MTD_PMC551_DEBUG 274#ifdef CONFIG_MTD_PMC551_DEBUG
268 printk(KERN_DEBUG "pmc551_read() done\n"); 275 printk(KERN_DEBUG "pmc551_read() done\n");
269#endif 276#endif
270 *retlen = copyto - buf; 277 *retlen = copyto - buf;
271 return 0; 278 return 0;
272} 279}
273 280
274static int pmc551_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) 281static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
282 size_t * retlen, const u_char * buf)
275{ 283{
276 struct mypriv *priv = mtd->priv; 284 struct mypriv *priv = mtd->priv;
277 u32 soff_hi, soff_lo; /* start address offset hi/lo */ 285 u32 soff_hi, soff_lo; /* start address offset hi/lo */
278 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */ 286 u32 eoff_hi, eoff_lo; /* end address offset hi/lo */
279 unsigned long end; 287 unsigned long end;
280 u_char *ptr; 288 u_char *ptr;
281 const u_char *copyfrom = buf; 289 const u_char *copyfrom = buf;
282
283 290
284#ifdef CONFIG_MTD_PMC551_DEBUG 291#ifdef CONFIG_MTD_PMC551_DEBUG
285 printk(KERN_DEBUG "pmc551_write(pos:%ld, len:%ld) asize:%ld\n", (long)to, (long)len, (long)priv->asize); 292 printk(KERN_DEBUG "pmc551_write(pos:%ld, len:%ld) asize:%ld\n",
293 (long)to, (long)len, (long)priv->asize);
286#endif 294#endif
287 295
288 end = to + len - 1; 296 end = to + len - 1;
289 /* Is it past the end? or did the u32 wrap? */ 297 /* Is it past the end? or did the u32 wrap? */
290 if (end > mtd->size ) { 298 if (end > mtd->size) {
291#ifdef CONFIG_MTD_PMC551_DEBUG 299#ifdef CONFIG_MTD_PMC551_DEBUG
292 printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, size: %ld, to: %ld)\n", (long) end, (long)mtd->size, (long)to); 300 printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, "
301 "size: %ld, to: %ld)\n", (long)end, (long)mtd->size,
302 (long)to);
293#endif 303#endif
294 return -EINVAL; 304 return -EINVAL;
295 } 305 }
296 306
297 soff_hi = to & ~(priv->asize - 1); 307 soff_hi = to & ~(priv->asize - 1);
298 eoff_hi = end & ~(priv->asize - 1); 308 eoff_hi = end & ~(priv->asize - 1);
299 soff_lo = to & (priv->asize - 1); 309 soff_lo = to & (priv->asize - 1);
300 eoff_lo = end & (priv->asize - 1); 310 eoff_lo = end & (priv->asize - 1);
301 311
302 pmc551_point (mtd, to, len, retlen, &ptr); 312 pmc551_point(mtd, to, len, retlen, &ptr);
303 313
304 if (soff_hi == eoff_hi) { 314 if (soff_hi == eoff_hi) {
305 /* The whole thing fits within one access, so just one shot 315 /* The whole thing fits within one access, so just one shot
306 will do it. */ 316 will do it. */
307 memcpy(ptr, copyfrom, len); 317 memcpy(ptr, copyfrom, len);
308 copyfrom += len; 318 copyfrom += len;
309 } else { 319 } else {
310 /* We have to do multiple writes to get all the data 320 /* We have to do multiple writes to get all the data
311 written. */ 321 written. */
312 while (soff_hi != eoff_hi) { 322 while (soff_hi != eoff_hi) {
313#ifdef CONFIG_MTD_PMC551_DEBUG 323#ifdef CONFIG_MTD_PMC551_DEBUG
314 printk( KERN_DEBUG "pmc551_write() soff_hi: %ld, eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi); 324 printk(KERN_DEBUG "pmc551_write() soff_hi: %ld, "
325 "eoff_hi: %ld\n", (long)soff_hi, (long)eoff_hi);
315#endif 326#endif
316 memcpy(ptr, copyfrom, priv->asize); 327 memcpy(ptr, copyfrom, priv->asize);
317 copyfrom += priv->asize; 328 copyfrom += priv->asize;
318 if (soff_hi >= mtd->size) { 329 if (soff_hi >= mtd->size) {
319 goto out; 330 goto out;
320 } 331 }
321 soff_hi += priv->asize; 332 soff_hi += priv->asize;
322 pmc551_point (mtd, soff_hi, priv->asize, retlen, &ptr); 333 pmc551_point(mtd, soff_hi, priv->asize, retlen, &ptr);
323 } 334 }
324 memcpy(ptr, copyfrom, eoff_lo); 335 memcpy(ptr, copyfrom, eoff_lo);
325 copyfrom += eoff_lo; 336 copyfrom += eoff_lo;
326 } 337 }
327 338
328out: 339 out:
329#ifdef CONFIG_MTD_PMC551_DEBUG 340#ifdef CONFIG_MTD_PMC551_DEBUG
330 printk(KERN_DEBUG "pmc551_write() done\n"); 341 printk(KERN_DEBUG "pmc551_write() done\n");
331#endif 342#endif
332 *retlen = copyfrom - buf; 343 *retlen = copyfrom - buf;
333 return 0; 344 return 0;
334} 345}
335 346
336/* 347/*
@@ -345,58 +356,58 @@ out:
345 * mechanism 356 * mechanism
346 * returns the size of the memory region found. 357 * returns the size of the memory region found.
347 */ 358 */
348static u32 fixup_pmc551 (struct pci_dev *dev) 359static u32 fixup_pmc551(struct pci_dev *dev)
349{ 360{
350#ifdef CONFIG_MTD_PMC551_BUGFIX 361#ifdef CONFIG_MTD_PMC551_BUGFIX
351 u32 dram_data; 362 u32 dram_data;
352#endif 363#endif
353 u32 size, dcmd, cfg, dtmp; 364 u32 size, dcmd, cfg, dtmp;
354 u16 cmd, tmp, i; 365 u16 cmd, tmp, i;
355 u8 bcmd, counter; 366 u8 bcmd, counter;
356 367
357 /* Sanity Check */ 368 /* Sanity Check */
358 if(!dev) { 369 if (!dev) {
359 return -ENODEV; 370 return -ENODEV;
360 } 371 }
361 372
362 /* 373 /*
363 * Attempt to reset the card 374 * Attempt to reset the card
364 * FIXME: Stop Spinning registers 375 * FIXME: Stop Spinning registers
365 */ 376 */
366 counter=0; 377 counter = 0;
367 /* unlock registers */ 378 /* unlock registers */
368 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, 0xA5 ); 379 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, 0xA5);
369 /* read in old data */ 380 /* read in old data */
370 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd ); 381 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd);
371 /* bang the reset line up and down for a few */ 382 /* bang the reset line up and down for a few */
372 for(i=0;i<10;i++) { 383 for (i = 0; i < 10; i++) {
373 counter=0; 384 counter = 0;
374 bcmd &= ~0x80; 385 bcmd &= ~0x80;
375 while(counter++ < 100) { 386 while (counter++ < 100) {
376 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 387 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
377 } 388 }
378 counter=0; 389 counter = 0;
379 bcmd |= 0x80; 390 bcmd |= 0x80;
380 while(counter++ < 100) { 391 while (counter++ < 100) {
381 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 392 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
382 } 393 }
383 } 394 }
384 bcmd |= (0x40|0x20); 395 bcmd |= (0x40 | 0x20);
385 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 396 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
386 397
387 /* 398 /*
388 * Take care and turn off the memory on the device while we 399 * Take care and turn off the memory on the device while we
389 * tweak the configurations 400 * tweak the configurations
390 */ 401 */
391 pci_read_config_word(dev, PCI_COMMAND, &cmd); 402 pci_read_config_word(dev, PCI_COMMAND, &cmd);
392 tmp = cmd & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY); 403 tmp = cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
393 pci_write_config_word(dev, PCI_COMMAND, tmp); 404 pci_write_config_word(dev, PCI_COMMAND, tmp);
394 405
395 /* 406 /*
396 * Disable existing aperture before probing memory size 407 * Disable existing aperture before probing memory size
397 */ 408 */
398 pci_read_config_dword(dev, PMC551_PCI_MEM_MAP0, &dcmd); 409 pci_read_config_dword(dev, PMC551_PCI_MEM_MAP0, &dcmd);
399 dtmp=(dcmd|PMC551_PCI_MEM_MAP_ENABLE|PMC551_PCI_MEM_MAP_REG_EN); 410 dtmp = (dcmd | PMC551_PCI_MEM_MAP_ENABLE | PMC551_PCI_MEM_MAP_REG_EN);
400 pci_write_config_dword(dev, PMC551_PCI_MEM_MAP0, dtmp); 411 pci_write_config_dword(dev, PMC551_PCI_MEM_MAP0, dtmp);
401 /* 412 /*
402 * Grab old BAR0 config so that we can figure out memory size 413 * Grab old BAR0 config so that we can figure out memory size
@@ -407,220 +418,230 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
407 * then write all 1's to the memory space, read back the result into 418 * then write all 1's to the memory space, read back the result into
408 * "size", and then write back all the old config. 419 * "size", and then write back all the old config.
409 */ 420 */
410 pci_read_config_dword( dev, PCI_BASE_ADDRESS_0, &cfg ); 421 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &cfg);
411#ifndef CONFIG_MTD_PMC551_BUGFIX 422#ifndef CONFIG_MTD_PMC551_BUGFIX
412 pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, ~0 ); 423 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, ~0);
413 pci_read_config_dword( dev, PCI_BASE_ADDRESS_0, &size ); 424 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &size);
414 size = (size&PCI_BASE_ADDRESS_MEM_MASK); 425 size = (size & PCI_BASE_ADDRESS_MEM_MASK);
415 size &= ~(size-1); 426 size &= ~(size - 1);
416 pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg ); 427 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, cfg);
417#else 428#else
418 /* 429 /*
419 * Get the size of the memory by reading all the DRAM size values 430 * Get the size of the memory by reading all the DRAM size values
420 * and adding them up. 431 * and adding them up.
421 * 432 *
422 * KLUDGE ALERT: the boards we are using have invalid column and 433 * KLUDGE ALERT: the boards we are using have invalid column and
423 * row mux values. We fix them here, but this will break other 434 * row mux values. We fix them here, but this will break other
424 * memory configurations. 435 * memory configurations.
425 */ 436 */
426 pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dram_data); 437 pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dram_data);
427 size = PMC551_DRAM_BLK_GET_SIZE(dram_data); 438 size = PMC551_DRAM_BLK_GET_SIZE(dram_data);
428 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 439 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
429 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 440 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
430 pci_write_config_dword(dev, PMC551_DRAM_BLK0, dram_data); 441 pci_write_config_dword(dev, PMC551_DRAM_BLK0, dram_data);
431 442
432 pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dram_data); 443 pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dram_data);
433 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 444 size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
434 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 445 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
435 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 446 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
436 pci_write_config_dword(dev, PMC551_DRAM_BLK1, dram_data); 447 pci_write_config_dword(dev, PMC551_DRAM_BLK1, dram_data);
437 448
438 pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dram_data); 449 pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dram_data);
439 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 450 size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
440 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 451 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
441 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 452 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
442 pci_write_config_dword(dev, PMC551_DRAM_BLK2, dram_data); 453 pci_write_config_dword(dev, PMC551_DRAM_BLK2, dram_data);
443 454
444 pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dram_data); 455 pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dram_data);
445 size += PMC551_DRAM_BLK_GET_SIZE(dram_data); 456 size += PMC551_DRAM_BLK_GET_SIZE(dram_data);
446 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5); 457 dram_data = PMC551_DRAM_BLK_SET_COL_MUX(dram_data, 0x5);
447 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9); 458 dram_data = PMC551_DRAM_BLK_SET_ROW_MUX(dram_data, 0x9);
448 pci_write_config_dword(dev, PMC551_DRAM_BLK3, dram_data); 459 pci_write_config_dword(dev, PMC551_DRAM_BLK3, dram_data);
449 460
450 /* 461 /*
451 * Oops .. something went wrong 462 * Oops .. something went wrong
452 */ 463 */
453 if( (size &= PCI_BASE_ADDRESS_MEM_MASK) == 0) { 464 if ((size &= PCI_BASE_ADDRESS_MEM_MASK) == 0) {
454 return -ENODEV; 465 return -ENODEV;
455 } 466 }
456#endif /* CONFIG_MTD_PMC551_BUGFIX */ 467#endif /* CONFIG_MTD_PMC551_BUGFIX */
457 468
458 if ((cfg&PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) { 469 if ((cfg & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) {
459 return -ENODEV; 470 return -ENODEV;
460 } 471 }
461 472
462 /* 473 /*
463 * Precharge Dram 474 * Precharge Dram
464 */ 475 */
465 pci_write_config_word( dev, PMC551_SDRAM_MA, 0x0400 ); 476 pci_write_config_word(dev, PMC551_SDRAM_MA, 0x0400);
466 pci_write_config_word( dev, PMC551_SDRAM_CMD, 0x00bf ); 477 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x00bf);
467 478
468 /* 479 /*
469 * Wait until command has gone through 480 * Wait until command has gone through
470 * FIXME: register spinning issue 481 * FIXME: register spinning issue
471 */ 482 */
472 do { pci_read_config_word( dev, PMC551_SDRAM_CMD, &cmd ); 483 do {
473 if(counter++ > 100)break; 484 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd);
474 } while ( (PCI_COMMAND_IO) & cmd ); 485 if (counter++ > 100)
475 486 break;
476 /* 487 } while ((PCI_COMMAND_IO) & cmd);
488
489 /*
477 * Turn on auto refresh 490 * Turn on auto refresh
478 * The loop is taken directly from Ramix's example code. I assume that 491 * The loop is taken directly from Ramix's example code. I assume that
479 * this must be held high for some duration of time, but I can find no 492 * this must be held high for some duration of time, but I can find no
480 * documentation refrencing the reasons why. 493 * documentation refrencing the reasons why.
481 */ 494 */
482 for ( i = 1; i<=8 ; i++) { 495 for (i = 1; i <= 8; i++) {
483 pci_write_config_word (dev, PMC551_SDRAM_CMD, 0x0df); 496 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x0df);
484 497
485 /* 498 /*
486 * Make certain command has gone through 499 * Make certain command has gone through
487 * FIXME: register spinning issue 500 * FIXME: register spinning issue
488 */ 501 */
489 counter=0; 502 counter = 0;
490 do { pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd); 503 do {
491 if(counter++ > 100)break; 504 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd);
492 } while ( (PCI_COMMAND_IO) & cmd ); 505 if (counter++ > 100)
493 } 506 break;
494 507 } while ((PCI_COMMAND_IO) & cmd);
495 pci_write_config_word ( dev, PMC551_SDRAM_MA, 0x0020); 508 }
496 pci_write_config_word ( dev, PMC551_SDRAM_CMD, 0x0ff); 509
497 510 pci_write_config_word(dev, PMC551_SDRAM_MA, 0x0020);
498 /* 511 pci_write_config_word(dev, PMC551_SDRAM_CMD, 0x0ff);
499 * Wait until command completes 512
500 * FIXME: register spinning issue 513 /*
501 */ 514 * Wait until command completes
502 counter=0; 515 * FIXME: register spinning issue
503 do { pci_read_config_word ( dev, PMC551_SDRAM_CMD, &cmd); 516 */
504 if(counter++ > 100)break; 517 counter = 0;
505 } while ( (PCI_COMMAND_IO) & cmd ); 518 do {
506 519 pci_read_config_word(dev, PMC551_SDRAM_CMD, &cmd);
507 pci_read_config_dword ( dev, PMC551_DRAM_CFG, &dcmd); 520 if (counter++ > 100)
508 dcmd |= 0x02000000; 521 break;
509 pci_write_config_dword ( dev, PMC551_DRAM_CFG, dcmd); 522 } while ((PCI_COMMAND_IO) & cmd);
510 523
511 /* 524 pci_read_config_dword(dev, PMC551_DRAM_CFG, &dcmd);
512 * Check to make certain fast back-to-back, if not 525 dcmd |= 0x02000000;
513 * then set it so 526 pci_write_config_dword(dev, PMC551_DRAM_CFG, dcmd);
514 */ 527
515 pci_read_config_word( dev, PCI_STATUS, &cmd); 528 /*
516 if((cmd&PCI_COMMAND_FAST_BACK) == 0) { 529 * Check to make certain fast back-to-back, if not
517 cmd |= PCI_COMMAND_FAST_BACK; 530 * then set it so
518 pci_write_config_word( dev, PCI_STATUS, cmd); 531 */
519 } 532 pci_read_config_word(dev, PCI_STATUS, &cmd);
520 533 if ((cmd & PCI_COMMAND_FAST_BACK) == 0) {
521 /* 534 cmd |= PCI_COMMAND_FAST_BACK;
522 * Check to make certain the DEVSEL is set correctly, this device 535 pci_write_config_word(dev, PCI_STATUS, cmd);
523 * has a tendancy to assert DEVSEL and TRDY when a write is performed 536 }
524 * to the memory when memory is read-only 537
525 */ 538 /*
526 if((cmd&PCI_STATUS_DEVSEL_MASK) != 0x0) { 539 * Check to make certain the DEVSEL is set correctly, this device
527 cmd &= ~PCI_STATUS_DEVSEL_MASK; 540 * has a tendancy to assert DEVSEL and TRDY when a write is performed
528 pci_write_config_word( dev, PCI_STATUS, cmd ); 541 * to the memory when memory is read-only
529 } 542 */
530 /* 543 if ((cmd & PCI_STATUS_DEVSEL_MASK) != 0x0) {
531 * Set to be prefetchable and put everything back based on old cfg. 544 cmd &= ~PCI_STATUS_DEVSEL_MASK;
545 pci_write_config_word(dev, PCI_STATUS, cmd);
546 }
547 /*
548 * Set to be prefetchable and put everything back based on old cfg.
532 * it's possible that the reset of the V370PDC nuked the original 549 * it's possible that the reset of the V370PDC nuked the original
533 * setup 550 * setup
534 */ 551 */
552 /*
553 cfg |= PCI_BASE_ADDRESS_MEM_PREFETCH;
554 pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg );
555 */
556
535 /* 557 /*
536 cfg |= PCI_BASE_ADDRESS_MEM_PREFETCH; 558 * Turn PCI memory and I/O bus access back on
537 pci_write_config_dword( dev, PCI_BASE_ADDRESS_0, cfg ); 559 */
538 */ 560 pci_write_config_word(dev, PCI_COMMAND,
539 561 PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
540 /*
541 * Turn PCI memory and I/O bus access back on
542 */
543 pci_write_config_word( dev, PCI_COMMAND,
544 PCI_COMMAND_MEMORY | PCI_COMMAND_IO );
545#ifdef CONFIG_MTD_PMC551_DEBUG 562#ifdef CONFIG_MTD_PMC551_DEBUG
546 /* 563 /*
547 * Some screen fun 564 * Some screen fun
548 */ 565 */
549 printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at 0x%llx\n", 566 printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at "
550 (size<1024)?size:(size<1048576)?size>>10:size>>20, 567 "0x%llx\n", (size < 1024) ? size : (size < 1048576) ?
551 (size<1024)?'B':(size<1048576)?'K':'M', 568 size >> 10 : size >> 20,
552 size, ((dcmd&(0x1<<3)) == 0)?"non-":"", 569 (size < 1024) ? 'B' : (size < 1048576) ? 'K' : 'M', size,
553 (unsigned long long)((dev->resource[0].start)&PCI_BASE_ADDRESS_MEM_MASK)); 570 ((dcmd & (0x1 << 3)) == 0) ? "non-" : "",
554 571 (unsigned long long)pci_resource_start(dev, 0));
555 /* 572
556 * Check to see the state of the memory 573 /*
557 */ 574 * Check to see the state of the memory
558 pci_read_config_dword( dev, PMC551_DRAM_BLK0, &dcmd ); 575 */
559 printk(KERN_DEBUG "pmc551: DRAM_BLK0 Flags: %s,%s\n" 576 pci_read_config_dword(dev, PMC551_DRAM_BLK0, &dcmd);
560 "pmc551: DRAM_BLK0 Size: %d at %d\n" 577 printk(KERN_DEBUG "pmc551: DRAM_BLK0 Flags: %s,%s\n"
561 "pmc551: DRAM_BLK0 Row MUX: %d, Col MUX: %d\n", 578 "pmc551: DRAM_BLK0 Size: %d at %d\n"
562 (((0x1<<1)&dcmd) == 0)?"RW":"RO", 579 "pmc551: DRAM_BLK0 Row MUX: %d, Col MUX: %d\n",
563 (((0x1<<0)&dcmd) == 0)?"Off":"On", 580 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
564 PMC551_DRAM_BLK_GET_SIZE(dcmd), 581 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
565 ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) ); 582 PMC551_DRAM_BLK_GET_SIZE(dcmd),
566 583 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
567 pci_read_config_dword( dev, PMC551_DRAM_BLK1, &dcmd ); 584 ((dcmd >> 9) & 0xF));
568 printk(KERN_DEBUG "pmc551: DRAM_BLK1 Flags: %s,%s\n" 585
569 "pmc551: DRAM_BLK1 Size: %d at %d\n" 586 pci_read_config_dword(dev, PMC551_DRAM_BLK1, &dcmd);
570 "pmc551: DRAM_BLK1 Row MUX: %d, Col MUX: %d\n", 587 printk(KERN_DEBUG "pmc551: DRAM_BLK1 Flags: %s,%s\n"
571 (((0x1<<1)&dcmd) == 0)?"RW":"RO", 588 "pmc551: DRAM_BLK1 Size: %d at %d\n"
572 (((0x1<<0)&dcmd) == 0)?"Off":"On", 589 "pmc551: DRAM_BLK1 Row MUX: %d, Col MUX: %d\n",
573 PMC551_DRAM_BLK_GET_SIZE(dcmd), 590 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
574 ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) ); 591 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
575 592 PMC551_DRAM_BLK_GET_SIZE(dcmd),
576 pci_read_config_dword( dev, PMC551_DRAM_BLK2, &dcmd ); 593 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
577 printk(KERN_DEBUG "pmc551: DRAM_BLK2 Flags: %s,%s\n" 594 ((dcmd >> 9) & 0xF));
578 "pmc551: DRAM_BLK2 Size: %d at %d\n" 595
579 "pmc551: DRAM_BLK2 Row MUX: %d, Col MUX: %d\n", 596 pci_read_config_dword(dev, PMC551_DRAM_BLK2, &dcmd);
580 (((0x1<<1)&dcmd) == 0)?"RW":"RO", 597 printk(KERN_DEBUG "pmc551: DRAM_BLK2 Flags: %s,%s\n"
581 (((0x1<<0)&dcmd) == 0)?"Off":"On", 598 "pmc551: DRAM_BLK2 Size: %d at %d\n"
582 PMC551_DRAM_BLK_GET_SIZE(dcmd), 599 "pmc551: DRAM_BLK2 Row MUX: %d, Col MUX: %d\n",
583 ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) ); 600 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
584 601 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
585 pci_read_config_dword( dev, PMC551_DRAM_BLK3, &dcmd ); 602 PMC551_DRAM_BLK_GET_SIZE(dcmd),
586 printk(KERN_DEBUG "pmc551: DRAM_BLK3 Flags: %s,%s\n" 603 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
587 "pmc551: DRAM_BLK3 Size: %d at %d\n" 604 ((dcmd >> 9) & 0xF));
588 "pmc551: DRAM_BLK3 Row MUX: %d, Col MUX: %d\n", 605
589 (((0x1<<1)&dcmd) == 0)?"RW":"RO", 606 pci_read_config_dword(dev, PMC551_DRAM_BLK3, &dcmd);
590 (((0x1<<0)&dcmd) == 0)?"Off":"On", 607 printk(KERN_DEBUG "pmc551: DRAM_BLK3 Flags: %s,%s\n"
591 PMC551_DRAM_BLK_GET_SIZE(dcmd), 608 "pmc551: DRAM_BLK3 Size: %d at %d\n"
592 ((dcmd>>20)&0x7FF), ((dcmd>>13)&0x7), ((dcmd>>9)&0xF) ); 609 "pmc551: DRAM_BLK3 Row MUX: %d, Col MUX: %d\n",
593 610 (((0x1 << 1) & dcmd) == 0) ? "RW" : "RO",
594 pci_read_config_word( dev, PCI_COMMAND, &cmd ); 611 (((0x1 << 0) & dcmd) == 0) ? "Off" : "On",
595 printk( KERN_DEBUG "pmc551: Memory Access %s\n", 612 PMC551_DRAM_BLK_GET_SIZE(dcmd),
596 (((0x1<<1)&cmd) == 0)?"off":"on" ); 613 ((dcmd >> 20) & 0x7FF), ((dcmd >> 13) & 0x7),
597 printk( KERN_DEBUG "pmc551: I/O Access %s\n", 614 ((dcmd >> 9) & 0xF));
598 (((0x1<<0)&cmd) == 0)?"off":"on" ); 615
599 616 pci_read_config_word(dev, PCI_COMMAND, &cmd);
600 pci_read_config_word( dev, PCI_STATUS, &cmd ); 617 printk(KERN_DEBUG "pmc551: Memory Access %s\n",
601 printk( KERN_DEBUG "pmc551: Devsel %s\n", 618 (((0x1 << 1) & cmd) == 0) ? "off" : "on");
602 ((PCI_STATUS_DEVSEL_MASK&cmd)==0x000)?"Fast": 619 printk(KERN_DEBUG "pmc551: I/O Access %s\n",
603 ((PCI_STATUS_DEVSEL_MASK&cmd)==0x200)?"Medium": 620 (((0x1 << 0) & cmd) == 0) ? "off" : "on");
604 ((PCI_STATUS_DEVSEL_MASK&cmd)==0x400)?"Slow":"Invalid" ); 621
605 622 pci_read_config_word(dev, PCI_STATUS, &cmd);
606 printk( KERN_DEBUG "pmc551: %sFast Back-to-Back\n", 623 printk(KERN_DEBUG "pmc551: Devsel %s\n",
607 ((PCI_COMMAND_FAST_BACK&cmd) == 0)?"Not ":"" ); 624 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x000) ? "Fast" :
608 625 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x200) ? "Medium" :
609 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd ); 626 ((PCI_STATUS_DEVSEL_MASK & cmd) == 0x400) ? "Slow" : "Invalid");
610 printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n" 627
611 "pmc551: System Control Register is %slocked to PCI access\n" 628 printk(KERN_DEBUG "pmc551: %sFast Back-to-Back\n",
612 "pmc551: System Control Register is %slocked to EEPROM access\n", 629 ((PCI_COMMAND_FAST_BACK & cmd) == 0) ? "Not " : "");
613 (bcmd&0x1)?"software":"hardware", 630
614 (bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un"); 631 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd);
632 printk(KERN_DEBUG "pmc551: EEPROM is under %s control\n"
633 "pmc551: System Control Register is %slocked to PCI access\n"
634 "pmc551: System Control Register is %slocked to EEPROM access\n",
635 (bcmd & 0x1) ? "software" : "hardware",
636 (bcmd & 0x20) ? "" : "un", (bcmd & 0x40) ? "" : "un");
615#endif 637#endif
616 return size; 638 return size;
617} 639}
618 640
619/* 641/*
620 * Kernel version specific module stuffages 642 * Kernel version specific module stuffages
621 */ 643 */
622 644
623
624MODULE_LICENSE("GPL"); 645MODULE_LICENSE("GPL");
625MODULE_AUTHOR("Mark Ferrell <mferrell@mvista.com>"); 646MODULE_AUTHOR("Mark Ferrell <mferrell@mvista.com>");
626MODULE_DESCRIPTION(PMC551_VERSION); 647MODULE_DESCRIPTION(PMC551_VERSION);
@@ -628,11 +649,11 @@ MODULE_DESCRIPTION(PMC551_VERSION);
628/* 649/*
629 * Stuff these outside the ifdef so as to not bust compiled in driver support 650 * Stuff these outside the ifdef so as to not bust compiled in driver support
630 */ 651 */
631static int msize=0; 652static int msize = 0;
632#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE) 653#if defined(CONFIG_MTD_PMC551_APERTURE_SIZE)
633static int asize=CONFIG_MTD_PMC551_APERTURE_SIZE 654static int asize = CONFIG_MTD_PMC551_APERTURE_SIZE
634#else 655#else
635static int asize=0; 656static int asize = 0;
636#endif 657#endif
637 658
638module_param(msize, int, 0); 659module_param(msize, int, 0);
@@ -645,164 +666,174 @@ MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]");
645 */ 666 */
646static int __init init_pmc551(void) 667static int __init init_pmc551(void)
647{ 668{
648 struct pci_dev *PCI_Device = NULL; 669 struct pci_dev *PCI_Device = NULL;
649 struct mypriv *priv; 670 struct mypriv *priv;
650 int count, found=0; 671 int count, found = 0;
651 struct mtd_info *mtd; 672 struct mtd_info *mtd;
652 u32 length = 0; 673 u32 length = 0;
653 674
654 if(msize) { 675 if (msize) {
655 msize = (1 << (ffs(msize) - 1))<<20; 676 msize = (1 << (ffs(msize) - 1)) << 20;
656 if (msize > (1<<30)) { 677 if (msize > (1 << 30)) {
657 printk(KERN_NOTICE "pmc551: Invalid memory size [%d]\n", msize); 678 printk(KERN_NOTICE "pmc551: Invalid memory size [%d]\n",
679 msize);
658 return -EINVAL; 680 return -EINVAL;
659 } 681 }
660 } 682 }
661 683
662 if(asize) { 684 if (asize) {
663 asize = (1 << (ffs(asize) - 1))<<20; 685 asize = (1 << (ffs(asize) - 1)) << 20;
664 if (asize > (1<<30) ) { 686 if (asize > (1 << 30)) {
665 printk(KERN_NOTICE "pmc551: Invalid aperture size [%d]\n", asize); 687 printk(KERN_NOTICE "pmc551: Invalid aperture size "
688 "[%d]\n", asize);
666 return -EINVAL; 689 return -EINVAL;
667 } 690 }
668 } 691 }
669 692
670 printk(KERN_INFO PMC551_VERSION); 693 printk(KERN_INFO PMC551_VERSION);
671 694
672 /* 695 /*
673 * PCU-bus chipset probe. 696 * PCU-bus chipset probe.
674 */ 697 */
675 for( count = 0; count < MAX_MTD_DEVICES; count++ ) { 698 for (count = 0; count < MAX_MTD_DEVICES; count++) {
676 699
677 if ((PCI_Device = pci_find_device(PCI_VENDOR_ID_V3_SEMI, 700 if ((PCI_Device = pci_get_device(PCI_VENDOR_ID_V3_SEMI,
678 PCI_DEVICE_ID_V3_SEMI_V370PDC, 701 PCI_DEVICE_ID_V3_SEMI_V370PDC,
679 PCI_Device ) ) == NULL) { 702 PCI_Device)) == NULL) {
680 break; 703 break;
681 } 704 }
682 705
683 printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%llx\n", 706 printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%llx\n",
684 (unsigned long long)PCI_Device->resource[0].start); 707 (unsigned long long)pci_resource_start(PCI_Device, 0));
685 708
686 /* 709 /*
687 * The PMC551 device acts VERY weird if you don't init it 710 * The PMC551 device acts VERY weird if you don't init it
688 * first. i.e. it will not correctly report devsel. If for 711 * first. i.e. it will not correctly report devsel. If for
689 * some reason the sdram is in a wrote-protected state the 712 * some reason the sdram is in a wrote-protected state the
690 * device will DEVSEL when it is written to causing problems 713 * device will DEVSEL when it is written to causing problems
691 * with the oldproc.c driver in 714 * with the oldproc.c driver in
692 * some kernels (2.2.*) 715 * some kernels (2.2.*)
693 */ 716 */
694 if((length = fixup_pmc551(PCI_Device)) <= 0) { 717 if ((length = fixup_pmc551(PCI_Device)) <= 0) {
695 printk(KERN_NOTICE "pmc551: Cannot init SDRAM\n"); 718 printk(KERN_NOTICE "pmc551: Cannot init SDRAM\n");
696 break; 719 break;
697 } 720 }
698 721
699 /* 722 /*
700 * This is needed until the driver is capable of reading the 723 * This is needed until the driver is capable of reading the
701 * onboard I2C SROM to discover the "real" memory size. 724 * onboard I2C SROM to discover the "real" memory size.
702 */ 725 */
703 if(msize) { 726 if (msize) {
704 length = msize; 727 length = msize;
705 printk(KERN_NOTICE "pmc551: Using specified memory size 0x%x\n", length); 728 printk(KERN_NOTICE "pmc551: Using specified memory "
729 "size 0x%x\n", length);
706 } else { 730 } else {
707 msize = length; 731 msize = length;
708 } 732 }
709 733
710 mtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); 734 mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
711 if (!mtd) { 735 if (!mtd) {
712 printk(KERN_NOTICE "pmc551: Cannot allocate new MTD device.\n"); 736 printk(KERN_NOTICE "pmc551: Cannot allocate new MTD "
713 break; 737 "device.\n");
714 } 738 break;
715 739 }
716 memset(mtd, 0, sizeof(struct mtd_info)); 740
717 741 priv = kzalloc(sizeof(struct mypriv), GFP_KERNEL);
718 priv = kmalloc (sizeof(struct mypriv), GFP_KERNEL); 742 if (!priv) {
719 if (!priv) { 743 printk(KERN_NOTICE "pmc551: Cannot allocate new MTD "
720 printk(KERN_NOTICE "pmc551: Cannot allocate new MTD device.\n"); 744 "device.\n");
721 kfree(mtd); 745 kfree(mtd);
722 break; 746 break;
723 } 747 }
724 memset(priv, 0, sizeof(*priv)); 748 mtd->priv = priv;
725 mtd->priv = priv; 749 priv->dev = PCI_Device;
726 priv->dev = PCI_Device; 750
727 751 if (asize > length) {
728 if(asize > length) { 752 printk(KERN_NOTICE "pmc551: reducing aperture size to "
729 printk(KERN_NOTICE "pmc551: reducing aperture size to fit %dM\n",length>>20); 753 "fit %dM\n", length >> 20);
730 priv->asize = asize = length; 754 priv->asize = asize = length;
731 } else if (asize == 0 || asize == length) { 755 } else if (asize == 0 || asize == length) {
732 printk(KERN_NOTICE "pmc551: Using existing aperture size %dM\n", length>>20); 756 printk(KERN_NOTICE "pmc551: Using existing aperture "
757 "size %dM\n", length >> 20);
733 priv->asize = asize = length; 758 priv->asize = asize = length;
734 } else { 759 } else {
735 printk(KERN_NOTICE "pmc551: Using specified aperture size %dM\n", asize>>20); 760 printk(KERN_NOTICE "pmc551: Using specified aperture "
761 "size %dM\n", asize >> 20);
736 priv->asize = asize; 762 priv->asize = asize;
737 } 763 }
738 priv->start = ioremap(((PCI_Device->resource[0].start) 764 priv->start = pci_iomap(PCI_Device, 0, priv->asize);
739 & PCI_BASE_ADDRESS_MEM_MASK),
740 priv->asize);
741 765
742 if (!priv->start) { 766 if (!priv->start) {
743 printk(KERN_NOTICE "pmc551: Unable to map IO space\n"); 767 printk(KERN_NOTICE "pmc551: Unable to map IO space\n");
744 kfree(mtd->priv); 768 kfree(mtd->priv);
745 kfree(mtd); 769 kfree(mtd);
746 break; 770 break;
747 } 771 }
748
749#ifdef CONFIG_MTD_PMC551_DEBUG 772#ifdef CONFIG_MTD_PMC551_DEBUG
750 printk( KERN_DEBUG "pmc551: setting aperture to %d\n", 773 printk(KERN_DEBUG "pmc551: setting aperture to %d\n",
751 ffs(priv->asize>>20)-1); 774 ffs(priv->asize >> 20) - 1);
752#endif 775#endif
753 776
754 priv->base_map0 = ( PMC551_PCI_MEM_MAP_REG_EN 777 priv->base_map0 = (PMC551_PCI_MEM_MAP_REG_EN
755 | PMC551_PCI_MEM_MAP_ENABLE 778 | PMC551_PCI_MEM_MAP_ENABLE
756 | (ffs(priv->asize>>20)-1)<<4 ); 779 | (ffs(priv->asize >> 20) - 1) << 4);
757 priv->curr_map0 = priv->base_map0; 780 priv->curr_map0 = priv->base_map0;
758 pci_write_config_dword ( priv->dev, PMC551_PCI_MEM_MAP0, 781 pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0,
759 priv->curr_map0 ); 782 priv->curr_map0);
760 783
761#ifdef CONFIG_MTD_PMC551_DEBUG 784#ifdef CONFIG_MTD_PMC551_DEBUG
762 printk( KERN_DEBUG "pmc551: aperture set to %d\n", 785 printk(KERN_DEBUG "pmc551: aperture set to %d\n",
763 (priv->base_map0 & 0xF0)>>4 ); 786 (priv->base_map0 & 0xF0) >> 4);
764#endif 787#endif
765 788
766 mtd->size = msize; 789 mtd->size = msize;
767 mtd->flags = MTD_CAP_RAM; 790 mtd->flags = MTD_CAP_RAM;
768 mtd->erase = pmc551_erase; 791 mtd->erase = pmc551_erase;
769 mtd->read = pmc551_read; 792 mtd->read = pmc551_read;
770 mtd->write = pmc551_write; 793 mtd->write = pmc551_write;
771 mtd->point = pmc551_point; 794 mtd->point = pmc551_point;
772 mtd->unpoint = pmc551_unpoint; 795 mtd->unpoint = pmc551_unpoint;
773 mtd->type = MTD_RAM; 796 mtd->type = MTD_RAM;
774 mtd->name = "PMC551 RAM board"; 797 mtd->name = "PMC551 RAM board";
775 mtd->erasesize = 0x10000; 798 mtd->erasesize = 0x10000;
776 mtd->writesize = 1; 799 mtd->writesize = 1;
777 mtd->owner = THIS_MODULE; 800 mtd->owner = THIS_MODULE;
778 801
779 if (add_mtd_device(mtd)) { 802 if (add_mtd_device(mtd)) {
780 printk(KERN_NOTICE "pmc551: Failed to register new device\n"); 803 printk(KERN_NOTICE "pmc551: Failed to register new "
781 iounmap(priv->start); 804 "device\n");
782 kfree(mtd->priv); 805 pci_iounmap(PCI_Device, priv->start);
783 kfree(mtd); 806 kfree(mtd->priv);
784 break; 807 kfree(mtd);
785 } 808 break;
786 printk(KERN_NOTICE "Registered pmc551 memory device.\n"); 809 }
787 printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n", 810
788 priv->asize>>20, 811 /* Keep a reference as the add_mtd_device worked */
789 priv->start, 812 pci_dev_get(PCI_Device);
790 priv->start + priv->asize); 813
791 printk(KERN_NOTICE "Total memory is %d%c\n", 814 printk(KERN_NOTICE "Registered pmc551 memory device.\n");
792 (length<1024)?length: 815 printk(KERN_NOTICE "Mapped %dM of memory from 0x%p to 0x%p\n",
793 (length<1048576)?length>>10:length>>20, 816 priv->asize >> 20,
794 (length<1024)?'B':(length<1048576)?'K':'M'); 817 priv->start, priv->start + priv->asize);
818 printk(KERN_NOTICE "Total memory is %d%c\n",
819 (length < 1024) ? length :
820 (length < 1048576) ? length >> 10 : length >> 20,
821 (length < 1024) ? 'B' : (length < 1048576) ? 'K' : 'M');
795 priv->nextpmc551 = pmc551list; 822 priv->nextpmc551 = pmc551list;
796 pmc551list = mtd; 823 pmc551list = mtd;
797 found++; 824 found++;
798 } 825 }
826
827 /* Exited early, reference left over */
828 if (PCI_Device)
829 pci_dev_put(PCI_Device);
799 830
800 if( !pmc551list ) { 831 if (!pmc551list) {
801 printk(KERN_NOTICE "pmc551: not detected\n"); 832 printk(KERN_NOTICE "pmc551: not detected\n");
802 return -ENODEV; 833 return -ENODEV;
803 } else { 834 } else {
804 printk(KERN_NOTICE "pmc551: %d pmc551 devices loaded\n", found); 835 printk(KERN_NOTICE "pmc551: %d pmc551 devices loaded\n", found);
805 return 0; 836 return 0;
806 } 837 }
807} 838}
808 839
@@ -811,23 +842,24 @@ static int __init init_pmc551(void)
811 */ 842 */
812static void __exit cleanup_pmc551(void) 843static void __exit cleanup_pmc551(void)
813{ 844{
814 int found=0; 845 int found = 0;
815 struct mtd_info *mtd; 846 struct mtd_info *mtd;
816 struct mypriv *priv; 847 struct mypriv *priv;
817 848
818 while((mtd=pmc551list)) { 849 while ((mtd = pmc551list)) {
819 priv = mtd->priv; 850 priv = mtd->priv;
820 pmc551list = priv->nextpmc551; 851 pmc551list = priv->nextpmc551;
821 852
822 if(priv->start) { 853 if (priv->start) {
823 printk (KERN_DEBUG "pmc551: unmapping %dM starting at 0x%p\n", 854 printk(KERN_DEBUG "pmc551: unmapping %dM starting at "
824 priv->asize>>20, priv->start); 855 "0x%p\n", priv->asize >> 20, priv->start);
825 iounmap (priv->start); 856 pci_iounmap(priv->dev, priv->start);
826 } 857 }
858 pci_dev_put(priv->dev);
827 859
828 kfree (mtd->priv); 860 kfree(mtd->priv);
829 del_mtd_device (mtd); 861 del_mtd_device(mtd);
830 kfree (mtd); 862 kfree(mtd);
831 found++; 863 found++;
832 } 864 }
833 865