0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/module.h>
0019 #include <linux/types.h>
0020 #include <linux/fs.h>
0021 #include <linux/errno.h>
0022 #include <linux/mm.h>
0023 #include <linux/delay.h>
0024 #include <linux/proc_fs.h>
0025 #include <linux/miscdevice.h>
0026 #include <linux/spinlock.h>
0027 #include <linux/rwsem.h>
0028 #include <linux/init.h>
0029 #include <linux/mutex.h>
0030 #include <linux/jiffies.h>
0031
0032 #include <asm/hardware/dec21285.h>
0033 #include <asm/io.h>
0034 #include <asm/mach-types.h>
0035 #include <linux/uaccess.h>
0036
0037
0038 #include <asm/nwflash.h>
0039
0040 #define NWFLASH_VERSION "6.4"
0041
0042 static DEFINE_MUTEX(flash_mutex);
0043 static void kick_open(void);
0044 static int get_flash_id(void);
0045 static int erase_block(int nBlock);
0046 static int write_block(unsigned long p, const char __user *buf, int count);
0047
0048 #define KFLASH_SIZE 1024*1024
0049 #define KFLASH_SIZE4 4*1024*1024
0050 #define KFLASH_ID 0x89A6
0051 #define KFLASH_ID4 0xB0D4
0052
0053 static bool flashdebug;
0054
0055 static int gbWriteEnable;
0056 static int gbWriteBase64Enable;
0057 static volatile unsigned char *FLASH_BASE;
0058 static int gbFlashSize = KFLASH_SIZE;
0059 static DEFINE_MUTEX(nwflash_mutex);
0060
0061 static int get_flash_id(void)
0062 {
0063 volatile unsigned int c1, c2;
0064
0065
0066
0067
0068 kick_open();
0069 c2 = inb(0x80);
0070 *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x90;
0071 udelay(15);
0072 c1 = *(volatile unsigned char *) FLASH_BASE;
0073 c2 = inb(0x80);
0074
0075
0076
0077
0078 if (c1 == 0xB0)
0079 c2 = *(volatile unsigned char *) (FLASH_BASE + 2);
0080 else
0081 c2 = *(volatile unsigned char *) (FLASH_BASE + 1);
0082
0083 c2 += (c1 << 8);
0084
0085
0086
0087
0088 *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
0089
0090 if (c2 == KFLASH_ID4)
0091 gbFlashSize = KFLASH_SIZE4;
0092
0093 return c2;
0094 }
0095
0096 static long flash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
0097 {
0098 mutex_lock(&flash_mutex);
0099 switch (cmd) {
0100 case CMD_WRITE_DISABLE:
0101 gbWriteBase64Enable = 0;
0102 gbWriteEnable = 0;
0103 break;
0104
0105 case CMD_WRITE_ENABLE:
0106 gbWriteEnable = 1;
0107 break;
0108
0109 case CMD_WRITE_BASE64K_ENABLE:
0110 gbWriteBase64Enable = 1;
0111 break;
0112
0113 default:
0114 gbWriteBase64Enable = 0;
0115 gbWriteEnable = 0;
0116 mutex_unlock(&flash_mutex);
0117 return -EINVAL;
0118 }
0119 mutex_unlock(&flash_mutex);
0120 return 0;
0121 }
0122
0123 static ssize_t flash_read(struct file *file, char __user *buf, size_t size,
0124 loff_t *ppos)
0125 {
0126 ssize_t ret;
0127
0128 if (flashdebug)
0129 printk(KERN_DEBUG "flash_read: flash_read: offset=0x%llx, "
0130 "buffer=%p, count=0x%zx.\n", *ppos, buf, size);
0131
0132
0133
0134 if (mutex_lock_interruptible(&nwflash_mutex))
0135 return -ERESTARTSYS;
0136
0137 ret = simple_read_from_buffer(buf, size, ppos, (void *)FLASH_BASE, gbFlashSize);
0138 mutex_unlock(&nwflash_mutex);
0139
0140 return ret;
0141 }
0142
0143 static ssize_t flash_write(struct file *file, const char __user *buf,
0144 size_t size, loff_t * ppos)
0145 {
0146 unsigned long p = *ppos;
0147 unsigned int count = size;
0148 int written;
0149 int nBlock, temp, rc;
0150 int i, j;
0151
0152 if (flashdebug)
0153 printk("flash_write: offset=0x%lX, buffer=0x%p, count=0x%X.\n",
0154 p, buf, count);
0155
0156 if (!gbWriteEnable)
0157 return -EINVAL;
0158
0159 if (p < 64 * 1024 && (!gbWriteBase64Enable))
0160 return -EINVAL;
0161
0162
0163
0164
0165 if (p >= gbFlashSize)
0166 return count ? -ENXIO : 0;
0167
0168 if (count > gbFlashSize - p)
0169 count = gbFlashSize - p;
0170
0171 if (!access_ok(buf, count))
0172 return -EFAULT;
0173
0174
0175
0176
0177 if (mutex_lock_interruptible(&nwflash_mutex))
0178 return -ERESTARTSYS;
0179
0180 written = 0;
0181
0182 nBlock = (int) p >> 16;
0183
0184
0185
0186
0187 temp = ((int) (p + count) >> 16) - nBlock + 1;
0188
0189
0190
0191
0192 if (((int) (p + count) & 0xFFFF) == 0)
0193 temp -= 1;
0194
0195 if (flashdebug)
0196 printk(KERN_DEBUG "flash_write: writing %d block(s) "
0197 "starting at %d.\n", temp, nBlock);
0198
0199 for (; temp; temp--, nBlock++) {
0200 if (flashdebug)
0201 printk(KERN_DEBUG "flash_write: erasing block %d.\n", nBlock);
0202
0203
0204
0205
0206 i = 0;
0207 j = 0;
0208 RetryBlock:
0209 do {
0210 rc = erase_block(nBlock);
0211 i++;
0212 } while (rc && i < 10);
0213
0214 if (rc) {
0215 printk(KERN_ERR "flash_write: erase error %x\n", rc);
0216 break;
0217 }
0218 if (flashdebug)
0219 printk(KERN_DEBUG "flash_write: writing offset %lX, "
0220 "from buf %p, bytes left %X.\n", p, buf,
0221 count - written);
0222
0223
0224
0225
0226 rc = write_block(p, buf, count - written);
0227 j++;
0228
0229
0230
0231
0232 if (!rc) {
0233
0234
0235
0236 if (j < 10)
0237 goto RetryBlock;
0238 else
0239
0240
0241
0242 rc = -1;
0243
0244 }
0245 if (rc < 0) {
0246 printk(KERN_ERR "flash_write: write error %X\n", rc);
0247 break;
0248 }
0249 p += rc;
0250 buf += rc;
0251 written += rc;
0252 *ppos += rc;
0253
0254 if (flashdebug)
0255 printk(KERN_DEBUG "flash_write: written 0x%X bytes OK.\n", written);
0256 }
0257
0258 mutex_unlock(&nwflash_mutex);
0259
0260 return written;
0261 }
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272 static loff_t flash_llseek(struct file *file, loff_t offset, int orig)
0273 {
0274 loff_t ret;
0275
0276 mutex_lock(&flash_mutex);
0277 if (flashdebug)
0278 printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n",
0279 (unsigned int) offset, orig);
0280
0281 ret = no_seek_end_llseek_size(file, offset, orig, gbFlashSize);
0282 mutex_unlock(&flash_mutex);
0283 return ret;
0284 }
0285
0286
0287
0288
0289
0290
0291
0292 static int erase_block(int nBlock)
0293 {
0294 volatile unsigned int c1;
0295 volatile unsigned char *pWritePtr;
0296 unsigned long timeout;
0297 int temp, temp1;
0298
0299
0300
0301
0302 *CSR_ROMWRITEREG = 0;
0303
0304
0305
0306
0307 c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
0308
0309 kick_open();
0310
0311
0312
0313 *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
0314
0315
0316
0317
0318
0319 pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + 0x8000 + (nBlock << 16)));
0320
0321
0322
0323 c1 = *pWritePtr;
0324
0325 kick_open();
0326
0327
0328
0329 *(volatile unsigned char *) pWritePtr = 0x20;
0330
0331
0332
0333
0334 *(volatile unsigned char *) pWritePtr = 0xD0;
0335
0336
0337
0338
0339 msleep(10);
0340
0341
0342
0343
0344 timeout = jiffies + 10 * HZ;
0345 c1 = 0;
0346 while (!(c1 & 0x80) && time_before(jiffies, timeout)) {
0347 msleep(10);
0348
0349
0350
0351 c1 = *(volatile unsigned char *) (pWritePtr);
0352
0353 }
0354
0355
0356
0357
0358 kick_open();
0359
0360 *(volatile unsigned char *) pWritePtr = 0xFF;
0361
0362
0363
0364
0365 if (c1 & 0x20) {
0366 printk(KERN_ERR "flash_erase: err at %p\n", pWritePtr);
0367
0368
0369
0370
0371 *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
0372 return -2;
0373 }
0374
0375
0376
0377
0378 msleep(10);
0379
0380 pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + (nBlock << 16)));
0381
0382 for (temp = 0; temp < 16 * 1024; temp++, pWritePtr += 4) {
0383 if ((temp1 = *(volatile unsigned int *) pWritePtr) != 0xFFFFFFFF) {
0384 printk(KERN_ERR "flash_erase: verify err at %p = %X\n",
0385 pWritePtr, temp1);
0386 return -1;
0387 }
0388 }
0389
0390 return 0;
0391
0392 }
0393
0394
0395
0396
0397 static int write_block(unsigned long p, const char __user *buf, int count)
0398 {
0399 volatile unsigned int c1;
0400 volatile unsigned int c2;
0401 unsigned char *pWritePtr;
0402 unsigned int uAddress;
0403 unsigned int offset;
0404 unsigned long timeout;
0405 unsigned long timeout1;
0406
0407 pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
0408
0409
0410
0411
0412 offset = p & 0xFFFF;
0413
0414 if (offset + count > 0x10000)
0415 count = 0x10000 - offset;
0416
0417
0418
0419
0420 timeout = jiffies + 30 * HZ;
0421
0422 for (offset = 0; offset < count; offset++, pWritePtr++) {
0423 uAddress = (unsigned int) pWritePtr;
0424 uAddress &= 0xFFFFFFFC;
0425 if (__get_user(c2, buf + offset))
0426 return -EFAULT;
0427
0428 WriteRetry:
0429
0430
0431
0432 c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
0433
0434
0435
0436
0437 kick_open();
0438
0439
0440
0441
0442 *CSR_ROMWRITEREG = (unsigned int) pWritePtr & 3;
0443
0444
0445
0446
0447 *(volatile unsigned char *) (uAddress) = 0x40;
0448
0449
0450
0451
0452 *(volatile unsigned char *) (uAddress) = c2;
0453
0454
0455
0456
0457 *(volatile unsigned char *) (FLASH_BASE + 0x10000) = 0x70;
0458
0459 c1 = 0;
0460
0461
0462
0463
0464 timeout1 = jiffies + 1 * HZ;
0465
0466
0467
0468
0469 while (!(c1 & 0x80) && time_before(jiffies, timeout1))
0470 c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
0471
0472
0473
0474
0475 if (time_after_eq(jiffies, timeout1)) {
0476 kick_open();
0477
0478
0479
0480 *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
0481
0482 goto WriteRetry;
0483 }
0484
0485
0486
0487 kick_open();
0488
0489
0490
0491 *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
0492
0493
0494
0495
0496
0497 if (c1 & 0x10) {
0498 kick_open();
0499
0500
0501
0502 *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
0503
0504
0505
0506
0507 if (time_before(jiffies, timeout)) {
0508 if (flashdebug)
0509 printk(KERN_DEBUG "write_block: Retrying write at 0x%X)n",
0510 pWritePtr - FLASH_BASE);
0511
0512
0513
0514
0515 msleep(10);
0516
0517 goto WriteRetry;
0518 } else {
0519 printk(KERN_ERR "write_block: timeout at 0x%X\n",
0520 pWritePtr - FLASH_BASE);
0521
0522
0523
0524 return -2;
0525
0526 }
0527 }
0528 }
0529
0530 msleep(10);
0531
0532 pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
0533
0534 for (offset = 0; offset < count; offset++) {
0535 char c, c1;
0536 if (__get_user(c, buf))
0537 return -EFAULT;
0538 buf++;
0539 if ((c1 = *pWritePtr++) != c) {
0540 printk(KERN_ERR "write_block: verify error at 0x%X (%02X!=%02X)\n",
0541 pWritePtr - FLASH_BASE, c1, c);
0542 return 0;
0543 }
0544 }
0545
0546 return count;
0547 }
0548
0549
0550 static void kick_open(void)
0551 {
0552 unsigned long flags;
0553
0554
0555
0556
0557
0558 raw_spin_lock_irqsave(&nw_gpio_lock, flags);
0559 nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE);
0560 raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
0561
0562
0563
0564
0565 udelay(25);
0566 }
0567
0568 static const struct file_operations flash_fops =
0569 {
0570 .owner = THIS_MODULE,
0571 .llseek = flash_llseek,
0572 .read = flash_read,
0573 .write = flash_write,
0574 .unlocked_ioctl = flash_ioctl,
0575 };
0576
0577 static struct miscdevice flash_miscdev =
0578 {
0579 NWFLASH_MINOR,
0580 "nwflash",
0581 &flash_fops
0582 };
0583
0584 static int __init nwflash_init(void)
0585 {
0586 int ret = -ENODEV;
0587
0588 if (machine_is_netwinder()) {
0589 int id;
0590
0591 FLASH_BASE = ioremap(DC21285_FLASH, KFLASH_SIZE4);
0592 if (!FLASH_BASE)
0593 goto out;
0594
0595 id = get_flash_id();
0596 if ((id != KFLASH_ID) && (id != KFLASH_ID4)) {
0597 ret = -ENXIO;
0598 iounmap((void *)FLASH_BASE);
0599 printk("Flash: incorrect ID 0x%04X.\n", id);
0600 goto out;
0601 }
0602
0603 printk("Flash ROM driver v.%s, flash device ID 0x%04X, size %d Mb.\n",
0604 NWFLASH_VERSION, id, gbFlashSize / (1024 * 1024));
0605
0606 ret = misc_register(&flash_miscdev);
0607 if (ret < 0) {
0608 iounmap((void *)FLASH_BASE);
0609 }
0610 }
0611 out:
0612 return ret;
0613 }
0614
0615 static void __exit nwflash_exit(void)
0616 {
0617 misc_deregister(&flash_miscdev);
0618 iounmap((void *)FLASH_BASE);
0619 }
0620
0621 MODULE_LICENSE("GPL");
0622
0623 module_param(flashdebug, bool, 0644);
0624
0625 module_init(nwflash_init);
0626 module_exit(nwflash_exit);