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