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        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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.