This source file includes following definitions.
- get_flash_id
 
- flash_ioctl
 
- flash_read
 
- flash_write
 
- flash_llseek
 
- erase_block
 
- write_block
 
- kick_open
 
- nwflash_init
 
- nwflash_exit
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 #include <linux/module.h>
  19 #include <linux/types.h>
  20 #include <linux/fs.h>
  21 #include <linux/errno.h>
  22 #include <linux/mm.h>
  23 #include <linux/delay.h>
  24 #include <linux/proc_fs.h>
  25 #include <linux/miscdevice.h>
  26 #include <linux/spinlock.h>
  27 #include <linux/rwsem.h>
  28 #include <linux/init.h>
  29 #include <linux/mutex.h>
  30 #include <linux/jiffies.h>
  31 
  32 #include <asm/hardware/dec21285.h>
  33 #include <asm/io.h>
  34 #include <asm/mach-types.h>
  35 #include <linux/uaccess.h>
  36 
  37 
  38 #include <asm/nwflash.h>
  39 
  40 #define NWFLASH_VERSION "6.4"
  41 
  42 static DEFINE_MUTEX(flash_mutex);
  43 static void kick_open(void);
  44 static int get_flash_id(void);
  45 static int erase_block(int nBlock);
  46 static int write_block(unsigned long p, const char __user *buf, int count);
  47 
  48 #define KFLASH_SIZE     1024*1024       
  49 #define KFLASH_SIZE4    4*1024*1024     
  50 #define KFLASH_ID       0x89A6          
  51 #define KFLASH_ID4      0xB0D4          
  52 
  53 static bool flashdebug;         
  54 
  55 static int gbWriteEnable;
  56 static int gbWriteBase64Enable;
  57 static volatile unsigned char *FLASH_BASE;
  58 static int gbFlashSize = KFLASH_SIZE;
  59 static DEFINE_MUTEX(nwflash_mutex);
  60 
  61 static int get_flash_id(void)
  62 {
  63         volatile unsigned int c1, c2;
  64 
  65         
  66 
  67 
  68         kick_open();
  69         c2 = inb(0x80);
  70         *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x90;
  71         udelay(15);
  72         c1 = *(volatile unsigned char *) FLASH_BASE;
  73         c2 = inb(0x80);
  74 
  75         
  76 
  77 
  78         if (c1 == 0xB0)
  79                 c2 = *(volatile unsigned char *) (FLASH_BASE + 2);
  80         else
  81                 c2 = *(volatile unsigned char *) (FLASH_BASE + 1);
  82 
  83         c2 += (c1 << 8);
  84 
  85         
  86 
  87 
  88         *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
  89 
  90         if (c2 == KFLASH_ID4)
  91                 gbFlashSize = KFLASH_SIZE4;
  92 
  93         return c2;
  94 }
  95 
  96 static long flash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
  97 {
  98         mutex_lock(&flash_mutex);
  99         switch (cmd) {
 100         case CMD_WRITE_DISABLE:
 101                 gbWriteBase64Enable = 0;
 102                 gbWriteEnable = 0;
 103                 break;
 104 
 105         case CMD_WRITE_ENABLE:
 106                 gbWriteEnable = 1;
 107                 break;
 108 
 109         case CMD_WRITE_BASE64K_ENABLE:
 110                 gbWriteBase64Enable = 1;
 111                 break;
 112 
 113         default:
 114                 gbWriteBase64Enable = 0;
 115                 gbWriteEnable = 0;
 116                 mutex_unlock(&flash_mutex);
 117                 return -EINVAL;
 118         }
 119         mutex_unlock(&flash_mutex);
 120         return 0;
 121 }
 122 
 123 static ssize_t flash_read(struct file *file, char __user *buf, size_t size,
 124                           loff_t *ppos)
 125 {
 126         ssize_t ret;
 127 
 128         if (flashdebug)
 129                 printk(KERN_DEBUG "flash_read: flash_read: offset=0x%llx, "
 130                        "buffer=%p, count=0x%zx.\n", *ppos, buf, size);
 131         
 132 
 133 
 134         if (mutex_lock_interruptible(&nwflash_mutex))
 135                 return -ERESTARTSYS;
 136 
 137         ret = simple_read_from_buffer(buf, size, ppos, (void *)FLASH_BASE, gbFlashSize);
 138         mutex_unlock(&nwflash_mutex);
 139 
 140         return ret;
 141 }
 142 
 143 static ssize_t flash_write(struct file *file, const char __user *buf,
 144                            size_t size, loff_t * ppos)
 145 {
 146         unsigned long p = *ppos;
 147         unsigned int count = size;
 148         int written;
 149         int nBlock, temp, rc;
 150         int i, j;
 151 
 152         if (flashdebug)
 153                 printk("flash_write: offset=0x%lX, buffer=0x%p, count=0x%X.\n",
 154                        p, buf, count);
 155 
 156         if (!gbWriteEnable)
 157                 return -EINVAL;
 158 
 159         if (p < 64 * 1024 && (!gbWriteBase64Enable))
 160                 return -EINVAL;
 161 
 162         
 163 
 164 
 165         if (p >= gbFlashSize)
 166                 return count ? -ENXIO : 0;
 167 
 168         if (count > gbFlashSize - p)
 169                 count = gbFlashSize - p;
 170                         
 171         if (!access_ok(buf, count))
 172                 return -EFAULT;
 173 
 174         
 175 
 176 
 177         if (mutex_lock_interruptible(&nwflash_mutex))
 178                 return -ERESTARTSYS;
 179 
 180         written = 0;
 181 
 182         nBlock = (int) p >> 16; 
 183 
 184         
 185 
 186 
 187         temp = ((int) (p + count) >> 16) - nBlock + 1;
 188 
 189         
 190 
 191 
 192         if (((int) (p + count) & 0xFFFF) == 0)
 193                 temp -= 1;
 194 
 195         if (flashdebug)
 196                 printk(KERN_DEBUG "flash_write: writing %d block(s) "
 197                         "starting at %d.\n", temp, nBlock);
 198 
 199         for (; temp; temp--, nBlock++) {
 200                 if (flashdebug)
 201                         printk(KERN_DEBUG "flash_write: erasing block %d.\n", nBlock);
 202 
 203                 
 204 
 205 
 206                 i = 0;
 207                 j = 0;
 208           RetryBlock:
 209                 do {
 210                         rc = erase_block(nBlock);
 211                         i++;
 212                 } while (rc && i < 10);
 213 
 214                 if (rc) {
 215                         printk(KERN_ERR "flash_write: erase error %x\n", rc);
 216                         break;
 217                 }
 218                 if (flashdebug)
 219                         printk(KERN_DEBUG "flash_write: writing offset %lX, "
 220                                "from buf %p, bytes left %X.\n", p, buf,
 221                                count - written);
 222 
 223                 
 224 
 225 
 226                 rc = write_block(p, buf, count - written);
 227                 j++;
 228 
 229                 
 230 
 231 
 232                 if (!rc) {
 233                         
 234 
 235 
 236                         if (j < 10)
 237                                 goto RetryBlock;
 238                         else
 239                                 
 240 
 241 
 242                                 rc = -1;
 243 
 244                 }
 245                 if (rc < 0) {
 246                         printk(KERN_ERR "flash_write: write error %X\n", rc);
 247                         break;
 248                 }
 249                 p += rc;
 250                 buf += rc;
 251                 written += rc;
 252                 *ppos += rc;
 253 
 254                 if (flashdebug)
 255                         printk(KERN_DEBUG "flash_write: written 0x%X bytes OK.\n", written);
 256         }
 257 
 258         mutex_unlock(&nwflash_mutex);
 259 
 260         return written;
 261 }
 262 
 263 
 264 
 265 
 266 
 267 
 268 
 269 
 270 
 271 
 272 static loff_t flash_llseek(struct file *file, loff_t offset, int orig)
 273 {
 274         loff_t ret;
 275 
 276         mutex_lock(&flash_mutex);
 277         if (flashdebug)
 278                 printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n",
 279                        (unsigned int) offset, orig);
 280 
 281         ret = no_seek_end_llseek_size(file, offset, orig, gbFlashSize);
 282         mutex_unlock(&flash_mutex);
 283         return ret;
 284 }
 285 
 286 
 287 
 288 
 289 
 290 
 291 
 292 static int erase_block(int nBlock)
 293 {
 294         volatile unsigned int c1;
 295         volatile unsigned char *pWritePtr;
 296         unsigned long timeout;
 297         int temp, temp1;
 298 
 299         
 300 
 301 
 302         *CSR_ROMWRITEREG = 0;
 303 
 304         
 305 
 306 
 307         c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
 308 
 309         kick_open();
 310         
 311 
 312 
 313         *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
 314 
 315         
 316 
 317 
 318 
 319         pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + 0x8000 + (nBlock << 16)));
 320         
 321 
 322 
 323         c1 = *pWritePtr;
 324 
 325         kick_open();
 326         
 327 
 328 
 329         *(volatile unsigned char *) pWritePtr = 0x20;
 330 
 331         
 332 
 333 
 334         *(volatile unsigned char *) pWritePtr = 0xD0;
 335 
 336         
 337 
 338 
 339         msleep(10);
 340 
 341         
 342 
 343 
 344         timeout = jiffies + 10 * HZ;
 345         c1 = 0;
 346         while (!(c1 & 0x80) && time_before(jiffies, timeout)) {
 347                 msleep(10);
 348                 
 349 
 350 
 351                 c1 = *(volatile unsigned char *) (pWritePtr);
 352                 
 353         }
 354 
 355         
 356 
 357 
 358         kick_open();
 359 
 360         *(volatile unsigned char *) pWritePtr = 0xFF;   
 361 
 362         
 363 
 364 
 365         if (c1 & 0x20) {
 366                 printk(KERN_ERR "flash_erase: err at %p\n", pWritePtr);
 367 
 368                 
 369 
 370 
 371                 *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
 372                 return -2;
 373         }
 374 
 375         
 376 
 377 
 378         msleep(10);
 379 
 380         pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + (nBlock << 16)));
 381 
 382         for (temp = 0; temp < 16 * 1024; temp++, pWritePtr += 4) {
 383                 if ((temp1 = *(volatile unsigned int *) pWritePtr) != 0xFFFFFFFF) {
 384                         printk(KERN_ERR "flash_erase: verify err at %p = %X\n",
 385                                pWritePtr, temp1);
 386                         return -1;
 387                 }
 388         }
 389 
 390         return 0;
 391 
 392 }
 393 
 394 
 395 
 396 
 397 static int write_block(unsigned long p, const char __user *buf, int count)
 398 {
 399         volatile unsigned int c1;
 400         volatile unsigned int c2;
 401         unsigned char *pWritePtr;
 402         unsigned int uAddress;
 403         unsigned int offset;
 404         unsigned long timeout;
 405         unsigned long timeout1;
 406 
 407         pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
 408 
 409         
 410 
 411 
 412         offset = p & 0xFFFF;
 413 
 414         if (offset + count > 0x10000)
 415                 count = 0x10000 - offset;
 416 
 417         
 418 
 419 
 420         timeout = jiffies + 30 * HZ;
 421 
 422         for (offset = 0; offset < count; offset++, pWritePtr++) {
 423                 uAddress = (unsigned int) pWritePtr;
 424                 uAddress &= 0xFFFFFFFC;
 425                 if (__get_user(c2, buf + offset))
 426                         return -EFAULT;
 427 
 428           WriteRetry:
 429                 
 430 
 431 
 432                 c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
 433 
 434                 
 435 
 436 
 437                 kick_open();
 438 
 439                 
 440 
 441 
 442                 *CSR_ROMWRITEREG = (unsigned int) pWritePtr & 3;
 443 
 444                 
 445 
 446 
 447                 *(volatile unsigned char *) (uAddress) = 0x40;
 448 
 449                 
 450 
 451 
 452                 *(volatile unsigned char *) (uAddress) = c2;
 453 
 454                 
 455 
 456 
 457                 *(volatile unsigned char *) (FLASH_BASE + 0x10000) = 0x70;
 458 
 459                 c1 = 0;
 460 
 461                 
 462 
 463 
 464                 timeout1 = jiffies + 1 * HZ;
 465 
 466                 
 467 
 468 
 469                 while (!(c1 & 0x80) && time_before(jiffies, timeout1))
 470                         c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
 471 
 472                 
 473 
 474 
 475                 if (time_after_eq(jiffies, timeout1)) {
 476                         kick_open();
 477                         
 478 
 479 
 480                         *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
 481 
 482                         goto WriteRetry;
 483                 }
 484                 
 485 
 486 
 487                 kick_open();
 488                 
 489 
 490 
 491                 *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
 492 
 493                 
 494 
 495 
 496 
 497                 if (c1 & 0x10) {
 498                         kick_open();
 499                         
 500 
 501 
 502                         *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
 503 
 504                         
 505 
 506 
 507                         if (time_before(jiffies, timeout)) {
 508                                 if (flashdebug)
 509                                         printk(KERN_DEBUG "write_block: Retrying write at 0x%X)n",
 510                                                pWritePtr - FLASH_BASE);
 511 
 512                                 
 513 
 514 
 515                                 msleep(10);
 516 
 517                                 goto WriteRetry;
 518                         } else {
 519                                 printk(KERN_ERR "write_block: timeout at 0x%X\n",
 520                                        pWritePtr - FLASH_BASE);
 521                                 
 522 
 523 
 524                                 return -2;
 525 
 526                         }
 527                 }
 528         }
 529 
 530         msleep(10);
 531 
 532         pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
 533 
 534         for (offset = 0; offset < count; offset++) {
 535                 char c, c1;
 536                 if (__get_user(c, buf))
 537                         return -EFAULT;
 538                 buf++;
 539                 if ((c1 = *pWritePtr++) != c) {
 540                         printk(KERN_ERR "write_block: verify error at 0x%X (%02X!=%02X)\n",
 541                                pWritePtr - FLASH_BASE, c1, c);
 542                         return 0;
 543                 }
 544         }
 545 
 546         return count;
 547 }
 548 
 549 
 550 static void kick_open(void)
 551 {
 552         unsigned long flags;
 553 
 554         
 555 
 556 
 557 
 558         raw_spin_lock_irqsave(&nw_gpio_lock, flags);
 559         nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE);
 560         raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
 561 
 562         
 563 
 564 
 565         udelay(25);
 566 }
 567 
 568 static const struct file_operations flash_fops =
 569 {
 570         .owner          = THIS_MODULE,
 571         .llseek         = flash_llseek,
 572         .read           = flash_read,
 573         .write          = flash_write,
 574         .unlocked_ioctl = flash_ioctl,
 575 };
 576 
 577 static struct miscdevice flash_miscdev =
 578 {
 579         FLASH_MINOR,
 580         "nwflash",
 581         &flash_fops
 582 };
 583 
 584 static int __init nwflash_init(void)
 585 {
 586         int ret = -ENODEV;
 587 
 588         if (machine_is_netwinder()) {
 589                 int id;
 590 
 591                 FLASH_BASE = ioremap(DC21285_FLASH, KFLASH_SIZE4);
 592                 if (!FLASH_BASE)
 593                         goto out;
 594 
 595                 id = get_flash_id();
 596                 if ((id != KFLASH_ID) && (id != KFLASH_ID4)) {
 597                         ret = -ENXIO;
 598                         iounmap((void *)FLASH_BASE);
 599                         printk("Flash: incorrect ID 0x%04X.\n", id);
 600                         goto out;
 601                 }
 602 
 603                 printk("Flash ROM driver v.%s, flash device ID 0x%04X, size %d Mb.\n",
 604                        NWFLASH_VERSION, id, gbFlashSize / (1024 * 1024));
 605 
 606                 ret = misc_register(&flash_miscdev);
 607                 if (ret < 0) {
 608                         iounmap((void *)FLASH_BASE);
 609                 }
 610         }
 611 out:
 612         return ret;
 613 }
 614 
 615 static void __exit nwflash_exit(void)
 616 {
 617         misc_deregister(&flash_miscdev);
 618         iounmap((void *)FLASH_BASE);
 619 }
 620 
 621 MODULE_LICENSE("GPL");
 622 
 623 module_param(flashdebug, bool, 0644);
 624 
 625 module_init(nwflash_init);
 626 module_exit(nwflash_exit);