~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/char/nwflash.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.