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

Archive Download this file



interactive