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