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