Changeset 9242


Ignore:
Timestamp:
03/06/08 00:34:24 (5 years ago)
Author:
BrainSlayer
Message:

fix erase function for supporting ranges bigger than eraseblock

Location:
src/linux/ar531x/linux-2.6.23/drivers/mtd/devices
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/linux/ar531x/linux-2.6.23/drivers/mtd/devices/spiflash.c

    r9156 r9242  
    204204#define SET_SPI_ACTIVITY()                                              \ 
    205205{                                                                                               \ 
    206         /*printk("SET_SPI @ %s, line %d\n",__FUNCTION__,__LINE__);*/            \ 
    207         while (atomic_read(&spiflash_cs))                       \ 
    208         {                                                                                       \ 
    209                 printk("Woops, shit happens @ %s, line %d !!!\n",__FUNCTION__,__LINE__);        \ 
    210                 udelay(1);                                                              \ 
    211         }                                                                                       \ 
    212         atomic_set(&spiflash_cs, 1);                            \ 
    213206} 
    214207 
    215208#define CLEAR_SPI_ACTIVITY()                                    \ 
    216209{                                                                                               \ 
    217         /*printk("CLEAR_SPI @ %s, line %d\n",__FUNCTION__,__LINE__);*/          \ 
    218210        chip_select(1);                                                         \ 
    219         atomic_set(&spiflash_cs, 0);                            \ 
    220211} 
    221212 
     
    368359{ 
    369360        struct opcodes *ptr_opcode; 
    370         u32 temp, reg; 
     361        __u32 temp, reg; 
     362        int finished = 0; 
     363        unsigned int addr = instr->addr; 
     364 
     365#ifdef SPIFLASH_DEBUG 
     366        printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len); 
     367#endif 
    371368 
    372369        /* sanity checks */ 
    373370        if (instr->addr + instr->len > mtd->size) return (-EINVAL); 
    374  
    375371        if (!spiflash_wait_ready(FL_ERASING)) 
    376372                return -EINTR; 
    377  
    378         spiflash_sendcmd(SPI_WRITE_ENABLE, 0); 
     373for (addr=instr->addr;addr<instr->addr+instr->len;addr+=mtd->erasesize) 
     374{ 
     375 
     376        ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; 
     377 
     378        temp = ((__u32)addr << 8) | (__u32)(ptr_opcode->code); 
     379        spiflash_sendcmd(SPI_WRITE_ENABLE,0); 
    379380        busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 
    380         reg = spiflash_regread32(SPI_FLASH_CTL); 
    381  
    382         ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; 
    383         temp = ((__u32)instr->addr << 8) | (__u32)(ptr_opcode->code); 
     381 
    384382        spiflash_regwrite32(SPI_FLASH_OPCODE, temp); 
    385383 
     
    387385        spiflash_regwrite32(SPI_FLASH_CTL, reg); 
    388386 
    389          
    390387        busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 
     388} 
    391389        spiflash_done(); 
    392390 
    393391        instr->state = MTD_ERASE_DONE; 
    394392        if (instr->callback) instr->callback (instr); 
    395  
    396         return 0; 
     393#ifdef SPIFLASH_DEBUG 
     394        printk (KERN_DEBUG "%s return\n",__FUNCTION__); 
     395#endif 
     396        return (0); 
    397397} 
    398398 
     
    518518 
    519519        /* wait and mark our activity */ 
     520        if (!spiflash_wait_ready(FL_WRITING)) 
     521                return -EINTR; 
    520522        SET_SPI_ACTIVITY(); 
    521523        chip_select(0); 
     
    565567        /* clean our activity */ 
    566568        CLEAR_SPI_ACTIVITY(); 
    567  
    568         for (;;) 
    569         { 
    570                 udelay(1); 
    571                 reg = spiflash_sendcmd(SPI_RD_STATUS, 0); 
    572                 if (!(reg & SPI_STATUS_WIP)) 
    573                 { 
    574                         break; 
    575                 } 
    576         } 
    577  
     569         
     570 
     571        busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 
     572        spiflash_done(); 
    578573        return; 
    579574} 
     
    597592        for (i=0; i<256; i++) buffer[i] = (unsigned char)i; 
    598593        page_write(block, buffer); 
     594        if (!spiflash_wait_ready(FL_WRITING)) 
     595                return -EINTR; 
    599596 
    600597        /* wait and mark our activity */ 
     
    642639        udelay(10); 
    643640 
    644         for (;;) 
    645         { 
    646                 udelay(1); 
    647                 reg = spiflash_sendcmd(SPI_RD_STATUS, 0); 
    648                 if (!(reg & SPI_STATUS_WIP)) break; 
    649         } 
    650          
     641        busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 
     642        spiflash_done(); 
    651643        printk("SPI flash write test done (%d)!, page programming is %s!\n", i, i<8 ? "disabled":"enabled"); 
    652644        return (i<8 ? 1:0); 
     
    654646 
    655647static int pp_mode = -1; 
    656 static int pp_enable = 0; 
     648static int pp_enable = 1; 
    657649 
    658650/* implementation for spiflash page programing. */ 
  • src/linux/ar531x/linux-2.6.23/drivers/mtd/devices/spiflash_selfmap.c

    r9159 r9242  
    4545#include <linux/squashfs_fs.h> 
    4646#include <linux/delay.h> 
     47#include <linux/proc_fs.h> 
    4748#include <asm/delay.h> 
    4849#include <asm/io.h> 
     
    147148        FL_READING, 
    148149        FL_ERASING, 
    149         FL_WRITING 
     150        FL_WRITING, 
     151        FL_SPI 
    150152}; 
    151153 
     
    155157        { name: "rootfs", offset: 0x0, size: 0x2b0000,}, //must be detected 
    156158        { name: "nvram", offset: 0x3d0000, size: 0x10000, }, 
    157         { name: "FIS directory", offset: 0x3e0000, size: 0x10000, }, 
     159        { name: "FIS Directory", offset: 0x3e0000, size: 0x10000, }, 
    158160        { name: "board_config", offset: 0x3f0000, size: 0x10000, }, 
    159161        { name: "fullflash", offset: 0x3f0000, size: 0x10000, }, 
     
    166168 
    167169extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts); 
     170 
     171#ifdef CONFIG_MTD_SPIFLASH_PP 
     172/* 
     173 * With AR2317, WRG-G19, we add the external circuit to implement page 
     174 * programming. The GPIO 0 is used to control the chip select of the SPI 
     175 * interface. The chip select is low active. 
     176 * 
     177 *                                                              david_hsieh@alphanetworks.com 
     178 */ 
     179 
     180/* The following part is cut from arch/mips/ar531x/ar531x.h */ 
     181 
     182#include <asm/addrspace.h> 
     183 
     184#define AR5315_DSLBASE          0xB1000000      /* RESET CONTROL MMR */ 
     185 
     186/* GPIO */ 
     187#define AR5315_GPIO_DI          (AR5315_DSLBASE + 0x0088) 
     188#define AR5315_GPIO_DO          (AR5315_DSLBASE + 0x0090) 
     189#define AR5315_GPIO_CR          (AR5315_DSLBASE + 0x0098) 
     190#define AR5315_GPIO_INT         (AR5315_DSLBASE + 0x00a0) 
     191 
     192/* Chip Select GPIO for Page Programming */ 
     193#ifndef CONFIG_MTD_SPIFLASH_PP_GPIO 
     194#define CONFIG_MTD_SPIFLASH_PP_GPIO 0 
     195#endif 
     196#define SPI_CS_BIT_MASK (1 << CONFIG_MTD_SPIFLASH_PP_GPIO) 
     197 
     198typedef unsigned int AR531X_REG; 
     199#define sysRegRead(phys)                (*(volatile AR531X_REG *)KSEG1ADDR(phys)) 
     200#define sysRegWrite(phys, val)  ((*(volatile AR531X_REG *)KSEG1ADDR(phys)) = (val)) 
     201 
     202static atomic_t spiflash_cs = ATOMIC_INIT(0); 
     203 
     204static inline void chip_select(int value) 
     205{ 
     206        __u32 reg; 
     207 
     208        /* Set GPIO 0 as output. */ 
     209        reg = sysRegRead(AR5315_GPIO_CR); 
     210        reg |= SPI_CS_BIT_MASK; 
     211        sysRegWrite(AR5315_GPIO_CR, reg); 
     212 
     213        /* Set GPIO 0 data. */ 
     214        reg = sysRegRead(AR5315_GPIO_DO); 
     215        if (value) reg |= SPI_CS_BIT_MASK; 
     216        else reg &= ~SPI_CS_BIT_MASK; 
     217        sysRegWrite(AR5315_GPIO_DO, reg); 
     218} 
     219 
     220#define SET_SPI_ACTIVITY()                                              \ 
     221{                                                                                               \ 
     222} 
     223 
     224#define CLEAR_SPI_ACTIVITY()                                    \ 
     225{                                                                                               \ 
     226        chip_select(1);                                                         \ 
     227} 
     228 
     229#else 
     230 
     231#define SET_SPI_ACTIVITY() 
     232#define CLEAR_SPI_ACTIVITY() 
     233 
     234#endif 
     235 
     236 
    168237 
    169238/***************************************************************************************************/ 
     
    287356                        return 0; 
    288357 
     358         
    289359                goto retry; 
    290360        } 
     
    307377        __u32 temp, reg; 
    308378        int finished = 0; 
     379        unsigned int addr = instr->addr; 
    309380 
    310381#ifdef SPIFLASH_DEBUG 
     
    314385        /* sanity checks */ 
    315386        if (instr->addr + instr->len > mtd->size) return (-EINVAL); 
     387        if (!spiflash_wait_ready(FL_ERASING)) 
     388                return -EINTR; 
     389for (addr=instr->addr;addr<instr->addr+instr->len;addr+=mtd->erasesize) 
     390{ 
    316391 
    317392        ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; 
    318393 
    319         temp = ((__u32)instr->addr << 8) | (__u32)(ptr_opcode->code); 
     394        temp = ((__u32)addr << 8) | (__u32)(ptr_opcode->code); 
    320395        spiflash_sendcmd(SPI_WRITE_ENABLE,0); 
    321         do { 
    322                 reg = spiflash_regread32(SPI_FLASH_CTL); 
    323         } while (reg & SPI_CTL_BUSY); 
     396        busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 
    324397 
    325398        spiflash_regwrite32(SPI_FLASH_OPCODE, temp); 
     
    328401        spiflash_regwrite32(SPI_FLASH_CTL, reg); 
    329402 
    330         do { 
    331                 reg = spiflash_sendcmd(SPI_RD_STATUS,0); 
    332                 if (!(reg & SPI_STATUS_WIP)) { 
    333                         finished = 1; 
    334                 } 
    335         } while (!finished); 
     403        busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 
     404} 
     405        spiflash_done(); 
    336406 
    337407        instr->state = MTD_ERASE_DONE; 
    338408        if (instr->callback) instr->callback (instr); 
    339  
    340409#ifdef SPIFLASH_DEBUG 
    341410        printk (KERN_DEBUG "%s return\n",__FUNCTION__); 
     
    445514} 
    446515 
     516#ifdef CONFIG_MTD_SPIFLASH_PP 
     517 
     518static void page_write(loff_t to, const u_char * buf) 
     519{ 
     520        __u32   reg, spi_data, opcode; 
     521        int             i; 
     522 
     523 
     524        /* We are going to write flash now, do write enable first. */ 
     525        spiflash_sendcmd(SPI_WRITE_ENABLE, 0); 
     526 
     527        /* we are not really waiting for CPU spiflash activity, just need the value of the register. */ 
     528        busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 
     529 
     530        /* Prepare SPI opcode, data and control register values. */ 
     531        opcode   = (stm_opcodes[SPI_PAGE_PROGRAM].code & SPI_OPCODE_MASK) | ((__u32)to << 8); 
     532        spi_data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; buf += 4; 
     533        reg      = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | 0x8 | SPI_CTL_START; 
     534 
     535        /* wait and mark our activity */ 
     536        if (!spiflash_wait_ready(FL_WRITING)) 
     537                return -EINTR; 
     538        SET_SPI_ACTIVITY(); 
     539        chip_select(0); 
     540 
     541        /* Send out the the first 4 bytes. */ 
     542        spiflash_regwrite32(SPI_FLASH_DATA, spi_data); 
     543        spiflash_regwrite32(SPI_FLASH_OPCODE, opcode); 
     544        spiflash_regwrite32(SPI_FLASH_CTL, reg); 
     545 
     546        /* 31 loops, each loop send 8 bytes */ 
     547        for (i=0; i<31; i++) 
     548        { 
     549                busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 
     550 
     551                /* 
     552                 * The sample code from the application node is: 
     553                 * 
     554                 *      spi_data = (UINT32)*((UINT32 *)buf); 
     555                 *      spi_data = cpi2le32(spi_data); 
     556                 *      spi_data_swapped = 
     557                 *                      (((spi_data>>8) & 0xff) << 24) | 
     558                 *                      (((spi_data>>24)& 0xff) << 8) | 
     559                 *                      (spi_data & 0x00ff00ff); 
     560                 */ 
     561                opcode   = (buf[3] <<  8) | (buf[2] << 16) | (buf[1] << 24) | buf[0]; buf += 4; 
     562                spi_data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] <<  8) | buf[0]; buf += 4; 
     563                reg      = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | 0x8 | SPI_CTL_START; 
     564 
     565                spiflash_regwrite32(SPI_FLASH_DATA, spi_data); 
     566                spiflash_regwrite32(SPI_FLASH_OPCODE, opcode); 
     567                spiflash_regwrite32(SPI_FLASH_CTL, reg); 
     568        } 
     569 
     570        /* send out the last 4 bytes */ 
     571        busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 
     572 
     573        opcode   = (buf[3] <<  8) | (buf[2] << 16) | (buf[1] << 24) | buf[0]; buf += 4; 
     574        reg      = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | 0x4 | SPI_CTL_START; 
     575 
     576        spiflash_regwrite32(SPI_FLASH_OPCODE, opcode); 
     577        spiflash_regwrite32(SPI_FLASH_CTL, reg); 
     578 
     579        busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 
     580 
     581        /* Deactive chip select */ 
     582        chip_select(1); 
     583        /* clean our activity */ 
     584        CLEAR_SPI_ACTIVITY(); 
     585         
     586 
     587        busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 
     588        spiflash_done(); 
     589        return; 
     590} 
     591 
     592/*  
     593 * Do page programming test. 
     594 * The 'block' should be erase already. 
     595 * We try to use page programming mode to write flash, 
     596 * and erase this block again before return. 
     597 */ 
     598static int test_page_programming(struct mtd_info * mtd, loff_t block) 
     599{ 
     600        unsigned char   buffer[256]; 
     601        unsigned char * flash; 
     602        struct opcodes *ptr_opcode; 
     603        __u32                   opcode, reg; 
     604        int                             i; 
     605 
     606 
     607        /* write the flash with known pattern */ 
     608        for (i=0; i<256; i++) buffer[i] = (unsigned char)i; 
     609        page_write(block, buffer); 
     610        if (!spiflash_wait_ready(FL_WRITING)) 
     611                return -EINTR; 
     612 
     613        /* wait and mark our activity */ 
     614        SET_SPI_ACTIVITY(); 
     615         
     616        /* read it back and check pattern */ 
     617        flash = (unsigned char *)(spidata->readaddr + block); 
     618        printk(KERN_EMERG "%s(): checking @ 0x%.8x ...\n",__FUNCTION__,(__u32)flash); 
     619        for (i = 0; i < 8; i++) 
     620        { 
     621                if (flash[i*4] != (unsigned char)(i*4)) 
     622                { 
     623                        printk(KERN_EMERG "unexpected value @ %d: 0x%02x !!\n", i*4, flash[i*4]); 
     624                        break; 
     625                } 
     626        } 
     627 
     628        /* clean our activity */ 
     629        CLEAR_SPI_ACTIVITY(); 
     630        udelay(10); 
     631         
     632        /* erase this block before return */ 
     633        printk(KERN_EMERG "%s(): erasing block 0x%.8x ...\n",__FUNCTION__,(__u32)block); 
     634 
     635        /* we are going to erase sector, do write enable first */ 
     636        spiflash_sendcmd(SPI_WRITE_ENABLE, 0); 
     637 
     638        /* wait and mark our activity */ 
     639        SET_SPI_ACTIVITY(); 
     640 
     641        /* we are not really waiting for CPU spiflash activity, just need the value of the register. */ 
     642        busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 
     643 
     644        /* send sector erase op. */ 
     645        ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; 
     646        opcode = ((__u32)ptr_opcode->code) | ((__u32)block << 8); 
     647        spiflash_regwrite32(SPI_FLASH_OPCODE, opcode); 
     648        reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | SPI_CTL_START; 
     649        spiflash_regwrite32(SPI_FLASH_CTL, reg); 
     650 
     651        /* wait for CPU spiflash activity */ 
     652        busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 
     653        /* clean our activity */ 
     654        CLEAR_SPI_ACTIVITY(); 
     655        udelay(10); 
     656 
     657        busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 
     658        spiflash_done(); 
     659        printk("SPI flash write test done (%d)!, page programming is %s!\n", i, i<8 ? "disabled":"enabled"); 
     660        return (i<8 ? 1:0); 
     661} 
     662 
     663static int pp_mode = -1; 
     664static int pp_enable = 1; 
     665 
     666/* implementation for spiflash page programing. */ 
     667static int spiflash_page_write(struct mtd_info * mtd, 
     668                loff_t to, size_t len, size_t * retlen, const u_char * buf) 
     669{ 
     670        size_t bytes_left = len; 
     671        size_t xact_len; 
     672        size_t written; 
     673        size_t offset; 
     674 
     675 
     676        /* If we already test page programming and failed, 
     677         * fall back to spiflash_write() directly. */ 
     678        if (pp_mode > 0) return spiflash_write(mtd, to, len, retlen, buf); 
     679 
     680        *retlen = 0; 
     681        if (to + len > mtd->size) return (-EINVAL); 
     682 
     683        while (bytes_left > 0) 
     684        { 
     685                offset = to % STM_PAGE_SIZE; 
     686                xact_len = MIN(bytes_left, STM_PAGE_SIZE - offset); 
     687                if (offset > 0 || xact_len < STM_PAGE_SIZE) 
     688                { 
     689                        spiflash_write(mtd, to, xact_len, &written, buf); 
     690                } 
     691                else 
     692                { 
     693                        /* test page program mode, if we did not test it before. */ 
     694                        if (pp_mode < 0) pp_mode = test_page_programming(mtd, to); 
     695 
     696                        if (pp_enable && (pp_mode == 0)) page_write(to, buf); 
     697                        else spiflash_write(mtd, to, xact_len, &written, buf); 
     698                } 
     699                to += xact_len; 
     700                bytes_left -= xact_len; 
     701                buf += xact_len; 
     702                *retlen += xact_len; 
     703        } 
     704 
     705        return 0; 
     706} 
     707 
     708static int __my_atoi(const char * buf) 
     709{ 
     710        int ret = 0; 
     711        while (*buf) 
     712        { 
     713                if (*buf >= '0' && *buf <= '9') ret += (int)(*buf - '0'); 
     714                buf++; 
     715        } 
     716        return ret; 
     717} 
     718 
     719static int proc_read_pp_enable(char * buf, char ** start, off_t offset, 
     720                int len, int * eof, void * data) 
     721{ 
     722        char * p = buf; 
     723        p += sprintf(p, "%d\n", pp_enable); 
     724        *eof = 1; 
     725        return p - buf; 
     726} 
     727 
     728static int proc_write_pp_enable(struct file * file, const char * buf, 
     729                unsigned long count, void * data) 
     730{ 
     731        pp_enable = __my_atoi(buf); 
     732        printk("spiflash: %s page programming!\n", pp_enable ? "enable" : "disable"); 
     733        if (pp_mode >= 0) printk("spiflash: H/W is %scapable of doing page programming!\n", pp_mode ? "not " : ""); 
     734        return count; 
     735} 
     736 
     737static struct proc_dir_entry * root = NULL; 
     738static struct proc_dir_entry * pp_enable_entry = NULL; 
     739 
     740static int register_spi_proc(void) 
     741{ 
     742        root = proc_mkdir("spiflash", NULL); 
     743        if (root == NULL) 
     744        { 
     745                printk("spiflash: fail to create /proc/spiflash !!\n"); 
     746                return -1; 
     747        } 
     748        pp_enable_entry = create_proc_entry("pp_enable", 0644, root); 
     749        if (pp_enable_entry == NULL) 
     750        { 
     751                printk("spiflash: fail to create /proc/spiflash/pp_enable !!\n"); 
     752                remove_proc_entry("spiflash", root); 
     753                root = NULL; 
     754                return -1; 
     755        } 
     756        pp_enable_entry->data = 0; 
     757        pp_enable_entry->read_proc = proc_read_pp_enable; 
     758        pp_enable_entry->write_proc = proc_write_pp_enable; 
     759        pp_enable_entry->owner = THIS_MODULE; 
     760        printk("spiflash: /proc/spiflash/pp_enable created !!\n"); 
     761        return 0; 
     762} 
     763 
     764static void remove_spi_proc(void) 
     765{ 
     766        if (pp_enable_entry) remove_proc_entry("pp_enable", root); 
     767        if (root) remove_proc_entry("spiflash", root); 
     768        pp_enable_entry = NULL; 
     769        root = NULL; 
     770} 
     771 
     772#endif 
    447773 
    448774#ifdef CONFIG_MTD_PARTITIONS 
     
    510836        mtd->erase = spiflash_erase; 
    511837        mtd->read = spiflash_read; 
    512         mtd->write = spiflash_write; 
     838#ifdef CONFIG_MTD_SPIFLASH_PP 
     839        mtd->write = spiflash_page_write; 
     840#else 
     841        mtd->write = spiflash_write; 
     842#endif 
    513843        mtd->owner = THIS_MODULE; 
    514844        printk(KERN_EMERG "scanning for root partition\n"); 
     
    562892        def:; 
    563893        result = add_mtd_partitions(mtd, dir_parts, 7); 
     894#ifdef CONFIG_MTD_SPIFLASH_PP 
     895                register_spi_proc(); 
     896#endif 
    564897        spidata->mtd = mtd; 
    565898         
     
    602935{ 
    603936        kfree(spidata); 
     937#ifdef CONFIG_MTD_SPIFLASH_PP 
     938        remove_spi_proc(); 
     939#endif 
    604940} 
    605941 
Note: See TracChangeset for help on using the changeset viewer.