Avoid ICE in get_random_int() with gcc-3.4.5
[linux-2.6] / drivers / char / nwflash.c
1 /*
2  * Flash memory interface rev.5 driver for the Intel
3  * Flash chips used on the NetWinder.
4  *
5  * 20/08/2000   RMK     use __ioremap to map flash into virtual memory
6  *                      make a few more places use "volatile"
7  * 22/05/2001   RMK     - Lock read against write
8  *                      - merge printk level changes (with mods) from Alan Cox.
9  *                      - use *ppos as the file position, not file->f_pos.
10  *                      - fix check for out of range pos and r/w size
11  *
12  * Please note that we are tampering with the only flash chip in the
13  * machine, which contains the bootup code.  We therefore have the
14  * power to convert these machines into doorstops...
15  */
16
17 #include <linux/module.h>
18 #include <linux/types.h>
19 #include <linux/fs.h>
20 #include <linux/errno.h>
21 #include <linux/mm.h>
22 #include <linux/delay.h>
23 #include <linux/proc_fs.h>
24 #include <linux/miscdevice.h>
25 #include <linux/spinlock.h>
26 #include <linux/rwsem.h>
27 #include <linux/init.h>
28 #include <linux/smp_lock.h>
29 #include <linux/mutex.h>
30
31 #include <asm/hardware/dec21285.h>
32 #include <asm/io.h>
33 #include <asm/leds.h>
34 #include <asm/mach-types.h>
35 #include <asm/system.h>
36 #include <asm/uaccess.h>
37
38 /*****************************************************************************/
39 #include <asm/nwflash.h>
40
41 #define NWFLASH_VERSION "6.4"
42
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       //1 Meg
49 #define KFLASH_SIZE4    4*1024*1024     //4 Meg
50 #define KFLASH_ID       0x89A6          //Intel flash
51 #define KFLASH_ID4      0xB0D4          //Intel flash 4Meg
52
53 static int flashdebug;          //if set - we will display progress msgs
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          * try to get flash chip ID
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          * on 4 Meg flash the second byte is actually at offset 2...
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          * set it back to read mode
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 int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg)
97 {
98         switch (cmd) {
99         case CMD_WRITE_DISABLE:
100                 gbWriteBase64Enable = 0;
101                 gbWriteEnable = 0;
102                 break;
103
104         case CMD_WRITE_ENABLE:
105                 gbWriteEnable = 1;
106                 break;
107
108         case CMD_WRITE_BASE64K_ENABLE:
109                 gbWriteBase64Enable = 1;
110                 break;
111
112         default:
113                 gbWriteBase64Enable = 0;
114                 gbWriteEnable = 0;
115                 return -EINVAL;
116         }
117         return 0;
118 }
119
120 static ssize_t flash_read(struct file *file, char __user *buf, size_t size,
121                           loff_t *ppos)
122 {
123         ssize_t ret;
124
125         if (flashdebug)
126                 printk(KERN_DEBUG "flash_read: flash_read: offset=0x%llx, "
127                        "buffer=%p, count=0x%zx.\n", *ppos, buf, size);
128         /*
129          * We now lock against reads and writes. --rmk
130          */
131         if (mutex_lock_interruptible(&nwflash_mutex))
132                 return -ERESTARTSYS;
133
134         ret = simple_read_from_buffer(buf, size, ppos, (void *)FLASH_BASE, gbFlashSize);
135         mutex_unlock(&nwflash_mutex);
136
137         return ret;
138 }
139
140 static ssize_t flash_write(struct file *file, const char __user *buf,
141                            size_t size, loff_t * ppos)
142 {
143         unsigned long p = *ppos;
144         unsigned int count = size;
145         int written;
146         int nBlock, temp, rc;
147         int i, j;
148
149         if (flashdebug)
150                 printk("flash_write: offset=0x%lX, buffer=0x%p, count=0x%X.\n",
151                        p, buf, count);
152
153         if (!gbWriteEnable)
154                 return -EINVAL;
155
156         if (p < 64 * 1024 && (!gbWriteBase64Enable))
157                 return -EINVAL;
158
159         /*
160          * check for out of range pos or count
161          */
162         if (p >= gbFlashSize)
163                 return count ? -ENXIO : 0;
164
165         if (count > gbFlashSize - p)
166                 count = gbFlashSize - p;
167                         
168         if (!access_ok(VERIFY_READ, buf, count))
169                 return -EFAULT;
170
171         /*
172          * We now lock against reads and writes. --rmk
173          */
174         if (mutex_lock_interruptible(&nwflash_mutex))
175                 return -ERESTARTSYS;
176
177         written = 0;
178
179         leds_event(led_claim);
180         leds_event(led_green_on);
181
182         nBlock = (int) p >> 16; //block # of 64K bytes
183
184         /*
185          * # of 64K blocks to erase and write
186          */
187         temp = ((int) (p + count) >> 16) - nBlock + 1;
188
189         /*
190          * write ends at exactly 64k boundary?
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                  * first we have to erase the block(s), where we will write...
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                  * write_block will limit write to space left in this block
225                  */
226                 rc = write_block(p, buf, count - written);
227                 j++;
228
229                 /*
230                  * if somehow write verify failed? Can't happen??
231                  */
232                 if (!rc) {
233                         /*
234                          * retry up to 10 times
235                          */
236                         if (j < 10)
237                                 goto RetryBlock;
238                         else
239                                 /*
240                                  * else quit with error...
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         /*
259          * restore reg on exit
260          */
261         leds_event(led_release);
262
263         mutex_unlock(&nwflash_mutex);
264
265         return written;
266 }
267
268
269 /*
270  * The memory devices use the full 32/64 bits of the offset, and so we cannot
271  * check against negative addresses: they are ok. The return value is weird,
272  * though, in that case (0).
273  *
274  * also note that seeking relative to the "end of file" isn't supported:
275  * it has no meaning, so it returns -EINVAL.
276  */
277 static loff_t flash_llseek(struct file *file, loff_t offset, int orig)
278 {
279         loff_t ret;
280
281         lock_kernel();
282         if (flashdebug)
283                 printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n",
284                        (unsigned int) offset, orig);
285
286         switch (orig) {
287         case 0:
288                 if (offset < 0) {
289                         ret = -EINVAL;
290                         break;
291                 }
292
293                 if ((unsigned int) offset > gbFlashSize) {
294                         ret = -EINVAL;
295                         break;
296                 }
297
298                 file->f_pos = (unsigned int) offset;
299                 ret = file->f_pos;
300                 break;
301         case 1:
302                 if ((file->f_pos + offset) > gbFlashSize) {
303                         ret = -EINVAL;
304                         break;
305                 }
306                 if ((file->f_pos + offset) < 0) {
307                         ret = -EINVAL;
308                         break;
309                 }
310                 file->f_pos += offset;
311                 ret = file->f_pos;
312                 break;
313         default:
314                 ret = -EINVAL;
315         }
316         unlock_kernel();
317         return ret;
318 }
319
320
321 /*
322  * assume that main Write routine did the parameter checking...
323  * so just go ahead and erase, what requested!
324  */
325
326 static int erase_block(int nBlock)
327 {
328         volatile unsigned int c1;
329         volatile unsigned char *pWritePtr;
330         unsigned long timeout;
331         int temp, temp1;
332
333         /*
334          * orange LED == erase
335          */
336         leds_event(led_amber_on);
337
338         /*
339          * reset footbridge to the correct offset 0 (...0..3)
340          */
341         *CSR_ROMWRITEREG = 0;
342
343         /*
344          * dummy ROM read
345          */
346         c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
347
348         kick_open();
349         /*
350          * reset status if old errors
351          */
352         *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
353
354         /*
355          * erase a block...
356          * aim at the middle of a current block...
357          */
358         pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + 0x8000 + (nBlock << 16)));
359         /*
360          * dummy read
361          */
362         c1 = *pWritePtr;
363
364         kick_open();
365         /*
366          * erase
367          */
368         *(volatile unsigned char *) pWritePtr = 0x20;
369
370         /*
371          * confirm
372          */
373         *(volatile unsigned char *) pWritePtr = 0xD0;
374
375         /*
376          * wait 10 ms
377          */
378         msleep(10);
379
380         /*
381          * wait while erasing in process (up to 10 sec)
382          */
383         timeout = jiffies + 10 * HZ;
384         c1 = 0;
385         while (!(c1 & 0x80) && time_before(jiffies, timeout)) {
386                 msleep(10);
387                 /*
388                  * read any address
389                  */
390                 c1 = *(volatile unsigned char *) (pWritePtr);
391                 //              printk("Flash_erase: status=%X.\n",c1);
392         }
393
394         /*
395          * set flash for normal read access
396          */
397         kick_open();
398 //      *(volatile unsigned char*)(FLASH_BASE+0x8000) = 0xFF;
399         *(volatile unsigned char *) pWritePtr = 0xFF;   //back to normal operation
400
401         /*
402          * check if erase errors were reported
403          */
404         if (c1 & 0x20) {
405                 printk(KERN_ERR "flash_erase: err at %p\n", pWritePtr);
406
407                 /*
408                  * reset error
409                  */
410                 *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
411                 return -2;
412         }
413
414         /*
415          * just to make sure - verify if erased OK...
416          */
417         msleep(10);
418
419         pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + (nBlock << 16)));
420
421         for (temp = 0; temp < 16 * 1024; temp++, pWritePtr += 4) {
422                 if ((temp1 = *(volatile unsigned int *) pWritePtr) != 0xFFFFFFFF) {
423                         printk(KERN_ERR "flash_erase: verify err at %p = %X\n",
424                                pWritePtr, temp1);
425                         return -1;
426                 }
427         }
428
429         return 0;
430
431 }
432
433 /*
434  * write_block will limit number of bytes written to the space in this block
435  */
436 static int write_block(unsigned long p, const char __user *buf, int count)
437 {
438         volatile unsigned int c1;
439         volatile unsigned int c2;
440         unsigned char *pWritePtr;
441         unsigned int uAddress;
442         unsigned int offset;
443         unsigned long timeout;
444         unsigned long timeout1;
445
446         /*
447          * red LED == write
448          */
449         leds_event(led_amber_off);
450         leds_event(led_red_on);
451
452         pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
453
454         /*
455          * check if write will end in this block....
456          */
457         offset = p & 0xFFFF;
458
459         if (offset + count > 0x10000)
460                 count = 0x10000 - offset;
461
462         /*
463          * wait up to 30 sec for this block
464          */
465         timeout = jiffies + 30 * HZ;
466
467         for (offset = 0; offset < count; offset++, pWritePtr++) {
468                 uAddress = (unsigned int) pWritePtr;
469                 uAddress &= 0xFFFFFFFC;
470                 if (__get_user(c2, buf + offset))
471                         return -EFAULT;
472
473           WriteRetry:
474                 /*
475                  * dummy read
476                  */
477                 c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
478
479                 /*
480                  * kick open the write gate
481                  */
482                 kick_open();
483
484                 /*
485                  * program footbridge to the correct offset...0..3
486                  */
487                 *CSR_ROMWRITEREG = (unsigned int) pWritePtr & 3;
488
489                 /*
490                  * write cmd
491                  */
492                 *(volatile unsigned char *) (uAddress) = 0x40;
493
494                 /*
495                  * data to write
496                  */
497                 *(volatile unsigned char *) (uAddress) = c2;
498
499                 /*
500                  * get status
501                  */
502                 *(volatile unsigned char *) (FLASH_BASE + 0x10000) = 0x70;
503
504                 c1 = 0;
505
506                 /*
507                  * wait up to 1 sec for this byte
508                  */
509                 timeout1 = jiffies + 1 * HZ;
510
511                 /*
512                  * while not ready...
513                  */
514                 while (!(c1 & 0x80) && time_before(jiffies, timeout1))
515                         c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
516
517                 /*
518                  * if timeout getting status
519                  */
520                 if (time_after_eq(jiffies, timeout1)) {
521                         kick_open();
522                         /*
523                          * reset err
524                          */
525                         *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
526
527                         goto WriteRetry;
528                 }
529                 /*
530                  * switch on read access, as a default flash operation mode
531                  */
532                 kick_open();
533                 /*
534                  * read access
535                  */
536                 *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
537
538                 /*
539                  * if hardware reports an error writing, and not timeout - 
540                  * reset the chip and retry
541                  */
542                 if (c1 & 0x10) {
543                         kick_open();
544                         /*
545                          * reset err
546                          */
547                         *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
548
549                         /*
550                          * before timeout?
551                          */
552                         if (time_before(jiffies, timeout)) {
553                                 if (flashdebug)
554                                         printk(KERN_DEBUG "write_block: Retrying write at 0x%X)n",
555                                                pWritePtr - FLASH_BASE);
556
557                                 /*
558                                  * no LED == waiting
559                                  */
560                                 leds_event(led_amber_off);
561                                 /*
562                                  * wait couple ms
563                                  */
564                                 msleep(10);
565                                 /*
566                                  * red LED == write
567                                  */
568                                 leds_event(led_red_on);
569
570                                 goto WriteRetry;
571                         } else {
572                                 printk(KERN_ERR "write_block: timeout at 0x%X\n",
573                                        pWritePtr - FLASH_BASE);
574                                 /*
575                                  * return error -2
576                                  */
577                                 return -2;
578
579                         }
580                 }
581         }
582
583         /*
584          * green LED == read/verify
585          */
586         leds_event(led_amber_off);
587         leds_event(led_green_on);
588
589         msleep(10);
590
591         pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
592
593         for (offset = 0; offset < count; offset++) {
594                 char c, c1;
595                 if (__get_user(c, buf))
596                         return -EFAULT;
597                 buf++;
598                 if ((c1 = *pWritePtr++) != c) {
599                         printk(KERN_ERR "write_block: verify error at 0x%X (%02X!=%02X)\n",
600                                pWritePtr - FLASH_BASE, c1, c);
601                         return 0;
602                 }
603         }
604
605         return count;
606 }
607
608
609 static void kick_open(void)
610 {
611         unsigned long flags;
612
613         /*
614          * we want to write a bit pattern XXX1 to Xilinx to enable
615          * the write gate, which will be open for about the next 2ms.
616          */
617         spin_lock_irqsave(&nw_gpio_lock, flags);
618         nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE);
619         spin_unlock_irqrestore(&nw_gpio_lock, flags);
620
621         /*
622          * let the ISA bus to catch on...
623          */
624         udelay(25);
625 }
626
627 static const struct file_operations flash_fops =
628 {
629         .owner          = THIS_MODULE,
630         .llseek         = flash_llseek,
631         .read           = flash_read,
632         .write          = flash_write,
633         .ioctl          = flash_ioctl,
634 };
635
636 static struct miscdevice flash_miscdev =
637 {
638         FLASH_MINOR,
639         "nwflash",
640         &flash_fops
641 };
642
643 static int __init nwflash_init(void)
644 {
645         int ret = -ENODEV;
646
647         if (machine_is_netwinder()) {
648                 int id;
649
650                 FLASH_BASE = ioremap(DC21285_FLASH, KFLASH_SIZE4);
651                 if (!FLASH_BASE)
652                         goto out;
653
654                 id = get_flash_id();
655                 if ((id != KFLASH_ID) && (id != KFLASH_ID4)) {
656                         ret = -ENXIO;
657                         iounmap((void *)FLASH_BASE);
658                         printk("Flash: incorrect ID 0x%04X.\n", id);
659                         goto out;
660                 }
661
662                 printk("Flash ROM driver v.%s, flash device ID 0x%04X, size %d Mb.\n",
663                        NWFLASH_VERSION, id, gbFlashSize / (1024 * 1024));
664
665                 ret = misc_register(&flash_miscdev);
666                 if (ret < 0) {
667                         iounmap((void *)FLASH_BASE);
668                 }
669         }
670 out:
671         return ret;
672 }
673
674 static void __exit nwflash_exit(void)
675 {
676         misc_deregister(&flash_miscdev);
677         iounmap((void *)FLASH_BASE);
678 }
679
680 MODULE_LICENSE("GPL");
681
682 module_param(flashdebug, bool, 0644);
683
684 module_init(nwflash_init);
685 module_exit(nwflash_exit);