linux/drivers/char/nwflash.c
<<
>>
Prefs
   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        ret = no_seek_end_llseek_size(file, offset, orig, gbFlashSize);
 281        mutex_unlock(&flash_mutex);
 282        return ret;
 283}
 284
 285
 286/*
 287 * assume that main Write routine did the parameter checking...
 288 * so just go ahead and erase, what requested!
 289 */
 290
 291static int erase_block(int nBlock)
 292{
 293        volatile unsigned int c1;
 294        volatile unsigned char *pWritePtr;
 295        unsigned long timeout;
 296        int temp, temp1;
 297
 298        /*
 299         * reset footbridge to the correct offset 0 (...0..3)
 300         */
 301        *CSR_ROMWRITEREG = 0;
 302
 303        /*
 304         * dummy ROM read
 305         */
 306        c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
 307
 308        kick_open();
 309        /*
 310         * reset status if old errors
 311         */
 312        *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
 313
 314        /*
 315         * erase a block...
 316         * aim at the middle of a current block...
 317         */
 318        pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + 0x8000 + (nBlock << 16)));
 319        /*
 320         * dummy read
 321         */
 322        c1 = *pWritePtr;
 323
 324        kick_open();
 325        /*
 326         * erase
 327         */
 328        *(volatile unsigned char *) pWritePtr = 0x20;
 329
 330        /*
 331         * confirm
 332         */
 333        *(volatile unsigned char *) pWritePtr = 0xD0;
 334
 335        /*
 336         * wait 10 ms
 337         */
 338        msleep(10);
 339
 340        /*
 341         * wait while erasing in process (up to 10 sec)
 342         */
 343        timeout = jiffies + 10 * HZ;
 344        c1 = 0;
 345        while (!(c1 & 0x80) && time_before(jiffies, timeout)) {
 346                msleep(10);
 347                /*
 348                 * read any address
 349                 */
 350                c1 = *(volatile unsigned char *) (pWritePtr);
 351                //              printk("Flash_erase: status=%X.\n",c1);
 352        }
 353
 354        /*
 355         * set flash for normal read access
 356         */
 357        kick_open();
 358//      *(volatile unsigned char*)(FLASH_BASE+0x8000) = 0xFF;
 359        *(volatile unsigned char *) pWritePtr = 0xFF;   //back to normal operation
 360
 361        /*
 362         * check if erase errors were reported
 363         */
 364        if (c1 & 0x20) {
 365                printk(KERN_ERR "flash_erase: err at %p\n", pWritePtr);
 366
 367                /*
 368                 * reset error
 369                 */
 370                *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
 371                return -2;
 372        }
 373
 374        /*
 375         * just to make sure - verify if erased OK...
 376         */
 377        msleep(10);
 378
 379        pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + (nBlock << 16)));
 380
 381        for (temp = 0; temp < 16 * 1024; temp++, pWritePtr += 4) {
 382                if ((temp1 = *(volatile unsigned int *) pWritePtr) != 0xFFFFFFFF) {
 383                        printk(KERN_ERR "flash_erase: verify err at %p = %X\n",
 384                               pWritePtr, temp1);
 385                        return -1;
 386                }
 387        }
 388
 389        return 0;
 390
 391}
 392
 393/*
 394 * write_block will limit number of bytes written to the space in this block
 395 */
 396static int write_block(unsigned long p, const char __user *buf, int count)
 397{
 398        volatile unsigned int c1;
 399        volatile unsigned int c2;
 400        unsigned char *pWritePtr;
 401        unsigned int uAddress;
 402        unsigned int offset;
 403        unsigned long timeout;
 404        unsigned long timeout1;
 405
 406        pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
 407
 408        /*
 409         * check if write will end in this block....
 410         */
 411        offset = p & 0xFFFF;
 412
 413        if (offset + count > 0x10000)
 414                count = 0x10000 - offset;
 415
 416        /*
 417         * wait up to 30 sec for this block
 418         */
 419        timeout = jiffies + 30 * HZ;
 420
 421        for (offset = 0; offset < count; offset++, pWritePtr++) {
 422                uAddress = (unsigned int) pWritePtr;
 423                uAddress &= 0xFFFFFFFC;
 424                if (__get_user(c2, buf + offset))
 425                        return -EFAULT;
 426
 427          WriteRetry:
 428                /*
 429                 * dummy read
 430                 */
 431                c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
 432
 433                /*
 434                 * kick open the write gate
 435                 */
 436                kick_open();
 437
 438                /*
 439                 * program footbridge to the correct offset...0..3
 440                 */
 441                *CSR_ROMWRITEREG = (unsigned int) pWritePtr & 3;
 442
 443                /*
 444                 * write cmd
 445                 */
 446                *(volatile unsigned char *) (uAddress) = 0x40;
 447
 448                /*
 449                 * data to write
 450                 */
 451                *(volatile unsigned char *) (uAddress) = c2;
 452
 453                /*
 454                 * get status
 455                 */
 456                *(volatile unsigned char *) (FLASH_BASE + 0x10000) = 0x70;
 457
 458                c1 = 0;
 459
 460                /*
 461                 * wait up to 1 sec for this byte
 462                 */
 463                timeout1 = jiffies + 1 * HZ;
 464
 465                /*
 466                 * while not ready...
 467                 */
 468                while (!(c1 & 0x80) && time_before(jiffies, timeout1))
 469                        c1 = *(volatile unsigned char *) (FLASH_BASE + 0x8000);
 470
 471                /*
 472                 * if timeout getting status
 473                 */
 474                if (time_after_eq(jiffies, timeout1)) {
 475                        kick_open();
 476                        /*
 477                         * reset err
 478                         */
 479                        *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
 480
 481                        goto WriteRetry;
 482                }
 483                /*
 484                 * switch on read access, as a default flash operation mode
 485                 */
 486                kick_open();
 487                /*
 488                 * read access
 489                 */
 490                *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
 491
 492                /*
 493                 * if hardware reports an error writing, and not timeout - 
 494                 * reset the chip and retry
 495                 */
 496                if (c1 & 0x10) {
 497                        kick_open();
 498                        /*
 499                         * reset err
 500                         */
 501                        *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x50;
 502
 503                        /*
 504                         * before timeout?
 505                         */
 506                        if (time_before(jiffies, timeout)) {
 507                                if (flashdebug)
 508                                        printk(KERN_DEBUG "write_block: Retrying write at 0x%X)n",
 509                                               pWritePtr - FLASH_BASE);
 510
 511                                /*
 512                                 * wait couple ms
 513                                 */
 514                                msleep(10);
 515
 516                                goto WriteRetry;
 517                        } else {
 518                                printk(KERN_ERR "write_block: timeout at 0x%X\n",
 519                                       pWritePtr - FLASH_BASE);
 520                                /*
 521                                 * return error -2
 522                                 */
 523                                return -2;
 524
 525                        }
 526                }
 527        }
 528
 529        msleep(10);
 530
 531        pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p));
 532
 533        for (offset = 0; offset < count; offset++) {
 534                char c, c1;
 535                if (__get_user(c, buf))
 536                        return -EFAULT;
 537                buf++;
 538                if ((c1 = *pWritePtr++) != c) {
 539                        printk(KERN_ERR "write_block: verify error at 0x%X (%02X!=%02X)\n",
 540                               pWritePtr - FLASH_BASE, c1, c);
 541                        return 0;
 542                }
 543        }
 544
 545        return count;
 546}
 547
 548
 549static void kick_open(void)
 550{
 551        unsigned long flags;
 552
 553        /*
 554         * we want to write a bit pattern XXX1 to Xilinx to enable
 555         * the write gate, which will be open for about the next 2ms.
 556         */
 557        raw_spin_lock_irqsave(&nw_gpio_lock, flags);
 558        nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE);
 559        raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
 560
 561        /*
 562         * let the ISA bus to catch on...
 563         */
 564        udelay(25);
 565}
 566
 567static const struct file_operations flash_fops =
 568{
 569        .owner          = THIS_MODULE,
 570        .llseek         = flash_llseek,
 571        .read           = flash_read,
 572        .write          = flash_write,
 573        .unlocked_ioctl = flash_ioctl,
 574};
 575
 576static struct miscdevice flash_miscdev =
 577{
 578        FLASH_MINOR,
 579        "nwflash",
 580        &flash_fops
 581};
 582
 583static int __init nwflash_init(void)
 584{
 585        int ret = -ENODEV;
 586
 587        if (machine_is_netwinder()) {
 588                int id;
 589
 590                FLASH_BASE = ioremap(DC21285_FLASH, KFLASH_SIZE4);
 591                if (!FLASH_BASE)
 592                        goto out;
 593
 594                id = get_flash_id();
 595                if ((id != KFLASH_ID) && (id != KFLASH_ID4)) {
 596                        ret = -ENXIO;
 597                        iounmap((void *)FLASH_BASE);
 598                        printk("Flash: incorrect ID 0x%04X.\n", id);
 599                        goto out;
 600                }
 601
 602                printk("Flash ROM driver v.%s, flash device ID 0x%04X, size %d Mb.\n",
 603                       NWFLASH_VERSION, id, gbFlashSize / (1024 * 1024));
 604
 605                ret = misc_register(&flash_miscdev);
 606                if (ret < 0) {
 607                        iounmap((void *)FLASH_BASE);
 608                }
 609        }
 610out:
 611        return ret;
 612}
 613
 614static void __exit nwflash_exit(void)
 615{
 616        misc_deregister(&flash_miscdev);
 617        iounmap((void *)FLASH_BASE);
 618}
 619
 620MODULE_LICENSE("GPL");
 621
 622module_param(flashdebug, bool, 0644);
 623
 624module_init(nwflash_init);
 625module_exit(nwflash_exit);
 626