Changeset 7084


Ignore:
Timestamp:
2007-05-03T11:50:20+02:00 (9 years ago)
Author:
nbd
Message:

spiflash cleanup

Location:
trunk/target/linux/atheros-2.6/files/drivers/mtd/devices
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/atheros-2.6/files/drivers/mtd/devices/spiflash.c

    r6502 r7084  
    44 * 
    55 * Copyright (c) 2005-2006 Atheros Communications Inc. 
    6  * Copyright (C) 2006 FON Technology, SL. 
    7  * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> 
    8  * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> 
     6 * Copyright (C) 2006-2007 FON Technology, SL. 
     7 * Copyright (C) 2006-2007 Imre Kaloz <kaloz@openwrt.org> 
     8 * Copyright (C) 2006-2007 Felix Fietkau <nbd@openwrt.org> 
    99 * 
    1010 * This code is free software; you can redistribute it and/or modify 
     
    4141#include <linux/squashfs_fs.h> 
    4242#include <linux/root_dev.h> 
     43#include <linux/delay.h> 
    4344#include <asm/delay.h> 
    4445#include <asm/io.h> 
    4546#include "spiflash.h" 
    4647 
    47 /* debugging */ 
    48 /* #define SPIFLASH_DEBUG */ 
    49  
    5048#ifndef __BIG_ENDIAN 
    5149#error This driver currently only works with big endian CPU. 
     
    5452#define MAX_PARTS 32 
    5553 
    56 static char module_name[] = "spiflash"; 
     54#define SPIFLASH "spiflash: " 
    5755 
    5856#define MIN(a,b)        ((a) < (b) ? (a) : (b)) 
    59 #define FALSE   0 
    60 #define TRUE    1 
    61  
    62 #define ROOTFS_NAME     "rootfs" 
     57 
     58#define busy_wait(condition, wait) \ 
     59        do { \ 
     60                while (condition) { \ 
     61                        spin_unlock_bh(&spidata->mutex); \ 
     62                        if (wait > 1) \ 
     63                                msleep(wait); \ 
     64                        else if ((wait == 1) && need_resched()) \ 
     65                                schedule(); \ 
     66                        else \ 
     67                                udelay(1); \ 
     68                        spin_lock_bh(&spidata->mutex); \ 
     69                } \ 
     70        } while (0) 
     71                 
    6372 
    6473static __u32 spiflash_regread32(int reg); 
    6574static void spiflash_regwrite32(int reg, __u32 data); 
    66 static __u32 spiflash_sendcmd (int op); 
     75static __u32 spiflash_sendcmd (int op, u32 addr); 
    6776 
    6877int __init spiflash_init (void); 
     
    9099 
    91100/* Mapping of generic opcodes to STM serial flash opcodes */ 
     101#define SPI_WRITE_ENABLE    0 
     102#define SPI_WRITE_DISABLE   1 
     103#define SPI_RD_STATUS       2 
     104#define SPI_WR_STATUS       3 
     105#define SPI_RD_DATA         4 
     106#define SPI_FAST_RD_DATA    5 
     107#define SPI_PAGE_PROGRAM    6 
     108#define SPI_SECTOR_ERASE    7 
     109#define SPI_BULK_ERASE      8 
     110#define SPI_DEEP_PWRDOWN    9 
     111#define SPI_RD_SIG          10 
     112#define SPI_MAX_OPCODES     11 
     113 
    92114struct opcodes { 
    93115    __u16 code; 
     
    100122        {STM_OP_WR_STATUS, 1, 0}, 
    101123        {STM_OP_RD_DATA, 4, 4}, 
    102         {STM_OP_FAST_RD_DATA, 1, 0}, 
     124        {STM_OP_FAST_RD_DATA, 5, 0}, 
    103125        {STM_OP_PAGE_PGRM, 8, 0}, 
    104126        {STM_OP_SECTOR_ERASE, 4, 0}, 
    105127        {STM_OP_BULK_ERASE, 1, 0}, 
    106128        {STM_OP_DEEP_PWRDOWN, 1, 0}, 
    107         {STM_OP_RD_SIG, 4, 1} 
     129        {STM_OP_RD_SIG, 4, 1}, 
    108130}; 
    109131 
     
    112134        struct  mtd_info       *mtd;     
    113135        struct  mtd_partition  *parsed_parts;     /* parsed partitions */ 
    114         void    *spiflash_readaddr; /* memory mapped data for read  */ 
    115         void    *spiflash_mmraddr;  /* memory mapped register space */ 
     136        void    *readaddr; /* memory mapped data for read  */ 
     137        void    *mmraddr;  /* memory mapped register space */ 
     138        wait_queue_head_t wq; 
    116139        spinlock_t mutex; 
     140        int state; 
     141}; 
     142enum { 
     143        FL_READY, 
     144        FL_READING, 
     145        FL_ERASING, 
     146        FL_WRITING 
    117147}; 
    118148 
     
    126156spiflash_regread32(int reg) 
    127157{ 
    128         volatile __u32 *data = (__u32 *)(spidata->spiflash_mmraddr + reg); 
     158        volatile __u32 *data = (__u32 *)(spidata->mmraddr + reg); 
    129159 
    130160        return (*data); 
     
    134164spiflash_regwrite32(int reg, __u32 data) 
    135165{ 
    136         volatile __u32 *addr = (__u32 *)(spidata->spiflash_mmraddr + reg); 
     166        volatile __u32 *addr = (__u32 *)(spidata->mmraddr + reg); 
    137167 
    138168        *addr = data; 
     
    140170} 
    141171 
     172 
    142173static __u32  
    143 spiflash_sendcmd (int op) 
    144 { 
    145          __u32 reg; 
    146          __u32 mask; 
     174spiflash_sendcmd (int op, u32 addr) 
     175{ 
     176         u32 reg; 
     177         u32 mask; 
    147178        struct opcodes *ptr_opcode; 
    148179 
    149180        ptr_opcode = &stm_opcodes[op]; 
    150  
    151         do { 
    152                 reg = spiflash_regread32(SPI_FLASH_CTL); 
    153         } while (reg & SPI_CTL_BUSY); 
    154  
    155         spiflash_regwrite32(SPI_FLASH_OPCODE, ptr_opcode->code); 
     181        busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 
     182        spiflash_regwrite32(SPI_FLASH_OPCODE, ((u32) ptr_opcode->code) | (addr << 8)); 
    156183 
    157184        reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | ptr_opcode->tx_cnt | 
     
    159186 
    160187        spiflash_regwrite32(SPI_FLASH_CTL, reg); 
     188        busy_wait(spiflash_regread32(SPI_FLASH_CTL) & SPI_CTL_BUSY, 0); 
    161189  
    162         if (ptr_opcode->rx_cnt > 0) { 
    163                 do { 
    164                         reg = spiflash_regread32(SPI_FLASH_CTL); 
    165                 } while (reg & SPI_CTL_BUSY); 
    166  
    167                 reg = (__u32) spiflash_regread32(SPI_FLASH_DATA); 
    168  
    169                 switch (ptr_opcode->rx_cnt) { 
    170                 case 1: 
    171                         mask = 0x000000ff; 
    172                         break; 
    173                 case 2: 
    174                         mask = 0x0000ffff; 
    175                         break; 
    176                 case 3: 
    177                         mask = 0x00ffffff; 
    178                         break; 
    179                 default: 
    180                         mask = 0xffffffff; 
    181                         break; 
    182                 } 
    183  
    184                 reg &= mask; 
    185         } 
    186         else { 
    187                 reg = 0; 
    188         } 
     190        if (!ptr_opcode->rx_cnt) 
     191                return 0; 
     192 
     193        reg = (__u32) spiflash_regread32(SPI_FLASH_DATA); 
     194 
     195        switch (ptr_opcode->rx_cnt) { 
     196        case 1: 
     197                        mask = 0x000000ff; 
     198                        break; 
     199        case 2: 
     200                        mask = 0x0000ffff; 
     201                        break; 
     202        case 3: 
     203                        mask = 0x00ffffff; 
     204                        break; 
     205        default: 
     206                        mask = 0xffffffff; 
     207                        break; 
     208        } 
     209        reg &= mask; 
    189210 
    190211        return reg; 
    191212} 
     213 
     214 
    192215 
    193216/* Probe SPI flash device 
     
    202225         
    203226        /* Read the signature on the flash device */ 
    204         sig = spiflash_sendcmd(SPI_RD_SIG); 
     227        spin_lock_bh(&spidata->mutex); 
     228        sig = spiflash_sendcmd(SPI_RD_SIG, 0); 
     229        spin_unlock_bh(&spidata->mutex); 
    205230 
    206231        switch (sig) { 
     
    221246                break; 
    222247        default: 
    223                 printk (KERN_WARNING "%s: Read of flash device signature failed!\n", module_name); 
     248                printk (KERN_WARNING SPIFLASH "Read of flash device signature failed!\n"); 
    224249                return (0); 
    225250        } 
     
    229254 
    230255 
     256/* wait until the flash chip is ready and grab a lock */ 
     257static int spiflash_wait_ready(int state) 
     258{ 
     259        DECLARE_WAITQUEUE(wait, current); 
     260 
     261retry: 
     262        spin_lock_bh(&spidata->mutex); 
     263        if (spidata->state != FL_READY) { 
     264                set_current_state(TASK_UNINTERRUPTIBLE); 
     265                add_wait_queue(&spidata->wq, &wait); 
     266                spin_unlock_bh(&spidata->mutex); 
     267                schedule(); 
     268                remove_wait_queue(&spidata->wq, &wait); 
     269                 
     270                if(signal_pending(current)) 
     271                        return 0; 
     272 
     273                goto retry; 
     274        } 
     275        spidata->state = state; 
     276 
     277        return 1; 
     278} 
     279 
     280static inline void spiflash_done(void) 
     281{ 
     282        spidata->state = FL_READY; 
     283        spin_unlock_bh(&spidata->mutex); 
     284        wake_up(&spidata->wq); 
     285} 
     286 
    231287static int  
    232288spiflash_erase (struct mtd_info *mtd,struct erase_info *instr) 
    233289{ 
    234290        struct opcodes *ptr_opcode; 
    235         __u32 temp, reg; 
    236         int finished = FALSE; 
    237  
    238 #ifdef SPIFLASH_DEBUG 
    239         printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len); 
    240 #endif 
     291        u32 temp, reg; 
    241292 
    242293        /* sanity checks */ 
    243294        if (instr->addr + instr->len > mtd->size) return (-EINVAL); 
    244295 
     296        if (!spiflash_wait_ready(FL_ERASING)) 
     297                return -EINTR; 
     298 
     299        spiflash_sendcmd(SPI_WRITE_ENABLE, 0); 
     300        busy_wait((reg = spiflash_regread32(SPI_FLASH_CTL)) & SPI_CTL_BUSY, 0); 
     301        reg = spiflash_regread32(SPI_FLASH_CTL); 
     302 
    245303        ptr_opcode = &stm_opcodes[SPI_SECTOR_ERASE]; 
    246  
    247304        temp = ((__u32)instr->addr << 8) | (__u32)(ptr_opcode->code); 
    248         spin_lock(&spidata->mutex); 
    249         spiflash_sendcmd(SPI_WRITE_ENABLE); 
    250         do { 
    251                 schedule(); 
    252                 reg = spiflash_regread32(SPI_FLASH_CTL); 
    253         } while (reg & SPI_CTL_BUSY); 
    254  
    255305        spiflash_regwrite32(SPI_FLASH_OPCODE, temp); 
    256306 
     
    258308        spiflash_regwrite32(SPI_FLASH_CTL, reg); 
    259309 
    260         do { 
    261                 schedule(); 
    262                 reg = spiflash_sendcmd(SPI_RD_STATUS); 
    263                 if (!(reg & SPI_STATUS_WIP)) { 
    264                         finished = TRUE; 
    265                 } 
    266         } while (!finished); 
    267         spin_unlock(&spidata->mutex); 
     310        /* this will take some time */ 
     311        spin_unlock_bh(&spidata->mutex); 
     312        msleep(800); 
     313        spin_lock_bh(&spidata->mutex); 
     314         
     315        busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 20); 
     316        spiflash_done(); 
    268317 
    269318        instr->state = MTD_ERASE_DONE; 
    270319        if (instr->callback) instr->callback (instr); 
    271320 
    272 #ifdef SPIFLASH_DEBUG 
    273         printk (KERN_DEBUG "%s return\n",__FUNCTION__); 
    274 #endif 
    275         return (0); 
     321        return 0; 
    276322} 
    277323 
     
    279325spiflash_read (struct mtd_info *mtd, loff_t from,size_t len,size_t *retlen,u_char *buf) 
    280326{ 
    281         u_char  *read_addr; 
    282  
    283 #ifdef SPIFLASH_DEBUG 
    284         printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) from,(int)len);   
    285 #endif 
    286  
     327        u8 *read_addr; 
     328         
    287329        /* sanity checks */ 
    288330        if (!len) return (0); 
    289331        if (from + len > mtd->size) return (-EINVAL); 
    290332         
    291  
    292333        /* we always read len bytes */ 
    293334        *retlen = len; 
    294335 
    295         read_addr = (u_char *)(spidata->spiflash_readaddr + from); 
    296         spin_lock(&spidata->mutex); 
     336        if (!spiflash_wait_ready(FL_READING)) 
     337                return -EINTR; 
     338        read_addr = (u8 *)(spidata->readaddr + from); 
    297339        memcpy(buf, read_addr, len); 
    298         spin_unlock(&spidata->mutex); 
    299  
    300         return (0); 
     340        spiflash_done(); 
     341 
     342        return 0; 
    301343} 
    302344 
     
    304346spiflash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf) 
    305347{ 
    306         int done = FALSE, page_offset, bytes_left, finished; 
    307         __u32 xact_len, spi_data = 0, opcode, reg; 
    308  
    309 #ifdef SPIFLASH_DEBUG 
    310         printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) to,len);  
    311 #endif 
     348        u32 opcode, bytes_left; 
    312349 
    313350        *retlen = 0; 
    314          
     351 
    315352        /* sanity checks */ 
    316353        if (!len) return (0); 
     
    320357        bytes_left = len; 
    321358         
    322         while (done == FALSE) { 
     359        do { 
     360                u32 xact_len, reg, page_offset, spi_data = 0; 
     361 
    323362                xact_len = MIN(bytes_left, sizeof(__u32)); 
    324363 
     
    335374                } 
    336375 
    337                 spin_lock(&spidata->mutex); 
    338                 spiflash_sendcmd(SPI_WRITE_ENABLE); 
    339  
    340                 do { 
    341                         schedule(); 
    342                         reg = spiflash_regread32(SPI_FLASH_CTL); 
    343                 } while (reg & SPI_CTL_BUSY); 
    344          
     376                if (!spiflash_wait_ready(FL_WRITING)) 
     377                        return -EINTR; 
     378 
     379                spiflash_sendcmd(SPI_WRITE_ENABLE, 0); 
    345380                switch (xact_len) { 
    346381                        case 1: 
     
    358393                                break; 
    359394                        default: 
    360                                 printk("spiflash_write: default case\n"); 
     395                                spi_data = 0; 
    361396                                break; 
    362397                } 
     
    366401                spiflash_regwrite32(SPI_FLASH_OPCODE, opcode); 
    367402 
     403                reg = spiflash_regread32(SPI_FLASH_CTL); 
    368404                reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | (xact_len + 4) | SPI_CTL_START; 
    369405                spiflash_regwrite32(SPI_FLASH_CTL, reg); 
    370                 finished = FALSE; 
    371                  
    372                 do { 
    373                         schedule(); 
    374                         reg = spiflash_sendcmd(SPI_RD_STATUS); 
    375                         if (!(reg & SPI_STATUS_WIP)) { 
    376                                 finished = TRUE; 
    377                         } 
    378                 } while (!finished); 
    379                 spin_unlock(&spidata->mutex); 
     406 
     407                /* give the chip some time before we start busy waiting */ 
     408                spin_unlock_bh(&spidata->mutex); 
     409                schedule(); 
     410                spin_lock_bh(&spidata->mutex); 
     411 
     412                busy_wait(spiflash_sendcmd(SPI_RD_STATUS, 0) & SPI_STATUS_WIP, 0); 
     413                spiflash_done(); 
    380414 
    381415                bytes_left -= xact_len; 
     
    384418 
    385419                *retlen += xact_len; 
    386  
    387                 if (bytes_left == 0) { 
    388                         done = TRUE; 
    389                 } 
    390         } 
    391  
    392         return (0); 
     420        } while (bytes_left != 0); 
     421 
     422        return 0; 
    393423} 
    394424 
     
    401431static int spiflash_probe(struct platform_device *pdev) 
    402432{ 
    403         int i, result = -1; 
     433        int result = -1; 
    404434        int index, num_parts; 
    405435        struct mtd_info *mtd; 
    406436 
    407         spidata->spiflash_mmraddr = ioremap_nocache(SPI_FLASH_MMR, SPI_FLASH_MMR_SIZE); 
    408          
    409         if (!spidata->spiflash_mmraddr) { 
    410                 printk (KERN_WARNING "%s: Failed to map flash device\n", module_name); 
     437        spidata->mmraddr = ioremap_nocache(SPI_FLASH_MMR, SPI_FLASH_MMR_SIZE); 
     438        spin_lock_init(&spidata->mutex); 
     439        init_waitqueue_head(&spidata->wq); 
     440        spidata->state = FL_READY; 
     441         
     442        if (!spidata->mmraddr) { 
     443                printk (KERN_WARNING SPIFLASH "Failed to map flash device\n"); 
    411444                kfree(spidata); 
    412445                spidata = NULL; 
     
    416449        if (!mtd) { 
    417450                kfree(spidata); 
    418                 return (-ENXIO); 
     451                return -ENXIO; 
    419452        } 
    420453         
    421         printk ("MTD driver for SPI flash.\n"); 
    422         printk ("%s: Probing for Serial flash ...\n", module_name); 
    423454        if (!(index = spiflash_probe_chip())) { 
    424         printk (KERN_WARNING "%s: Found no serial flash device\n", module_name); 
    425                 kfree(mtd); 
    426                 kfree(spidata); 
    427         return (-ENXIO); 
     455        printk (KERN_WARNING SPIFLASH "Found no serial flash device\n"); 
     456                goto error; 
    428457        } 
    429458 
    430         printk ("%s: Found SPI serial Flash.\n", module_name); 
    431  
    432         spidata->spiflash_readaddr = ioremap_nocache(SPI_FLASH_READ, flashconfig_tbl[index].byte_cnt); 
    433         if (!spidata->spiflash_readaddr) { 
    434                 printk (KERN_WARNING "%s: Failed to map flash device\n", module_name); 
    435                 kfree(mtd); 
    436                 kfree(spidata); 
    437                 return (-ENXIO); 
     459        spidata->readaddr = ioremap_nocache(SPI_FLASH_READ, flashconfig_tbl[index].byte_cnt); 
     460        if (!spidata->readaddr) { 
     461                printk (KERN_WARNING SPIFLASH "Failed to map flash device\n"); 
     462                goto error; 
    438463        } 
    439464 
    440         mtd->name = module_name; 
     465        mtd->name = "spiflash"; 
    441466        mtd->type = MTD_NORFLASH; 
    442467        mtd->flags = (MTD_CAP_NORFLASH|MTD_WRITEABLE); 
     
    451476        mtd->owner = THIS_MODULE; 
    452477 
    453 #ifdef SPIFLASH_DEBUG 
    454         printk (KERN_DEBUG 
    455                    "mtd->name = %s\n" 
    456                    "mtd->size = 0x%.8x (%uM)\n" 
    457                    "mtd->erasesize = 0x%.8x (%uK)\n" 
    458                    "mtd->numeraseregions = %d\n", 
    459                    mtd->name, 
    460                    mtd->size, mtd->size / (1024*1024), 
    461                    mtd->erasesize, mtd->erasesize / 1024, 
    462                    mtd->numeraseregions); 
    463  
    464         if (mtd->numeraseregions) { 
    465                 for (result = 0; result < mtd->numeraseregions; result++) { 
    466                         printk (KERN_DEBUG 
    467                            "\n\n" 
    468                            "mtd->eraseregions[%d].offset = 0x%.8x\n" 
    469                            "mtd->eraseregions[%d].erasesize = 0x%.8x (%uK)\n" 
    470                            "mtd->eraseregions[%d].numblocks = %d\n", 
    471                            result,mtd->eraseregions[result].offset, 
    472                            result,mtd->eraseregions[result].erasesize,mtd->eraseregions[result].erasesize / 1024, 
    473                            result,mtd->eraseregions[result].numblocks); 
    474                 } 
    475         } 
    476 #endif 
    477478        /* parse redboot partitions */ 
    478479        num_parts = parse_mtd_partitions(mtd, part_probe_types, &spidata->parsed_parts, 0); 
    479  
    480 #ifdef SPIFLASH_DEBUG 
    481         printk (KERN_DEBUG "Found %d partitions\n", num_parts); 
    482 #endif 
    483         if (num_parts) { 
    484                 result = add_mtd_partitions(mtd, spidata->parsed_parts, num_parts); 
    485         } else { 
    486 #ifdef SPIFLASH_DEBUG 
    487                 printk (KERN_DEBUG "Did not find any partitions\n"); 
    488 #endif 
    489                 kfree(mtd); 
    490                 kfree(spidata); 
    491                 return (-ENXIO); 
    492         } 
    493  
     480        if (!num_parts) 
     481                goto error; 
     482 
     483        result = add_mtd_partitions(mtd, spidata->parsed_parts, num_parts); 
    494484        spidata->mtd = mtd; 
    495  
     485         
    496486        return (result); 
     487         
     488error: 
     489        kfree(mtd); 
     490        kfree(spidata); 
     491        return -ENXIO; 
    497492} 
    498493 
     
    501496        del_mtd_partitions (spidata->mtd); 
    502497        kfree(spidata->mtd); 
    503  
    504498        return 0; 
    505499} 
     
    534528 
    535529MODULE_LICENSE("GPL"); 
    536 MODULE_AUTHOR("Atheros Communications Inc"); 
     530MODULE_AUTHOR("OpenWrt.org, Atheros Communications Inc"); 
    537531MODULE_DESCRIPTION("MTD driver for SPI Flash on Atheros SOC"); 
    538532 
  • trunk/target/linux/atheros-2.6/files/drivers/mtd/devices/spiflash.h

    r6502 r7084  
    2222 
    2323#define STM_PAGE_SIZE           256 
    24  
    25 #define SPI_WRITE_ENABLE    0 
    26 #define SPI_WRITE_DISABLE   1 
    27 #define SPI_RD_STATUS       2 
    28 #define SPI_WR_STATUS       3 
    29 #define SPI_RD_DATA         4 
    30 #define SPI_FAST_RD_DATA    5 
    31 #define SPI_PAGE_PROGRAM    6 
    32 #define SPI_SECTOR_ERASE    7 
    33 #define SPI_BULK_ERASE      8 
    34 #define SPI_DEEP_PWRDOWN    9 
    35 #define SPI_RD_SIG          10 
    36 #define SPI_MAX_OPCODES     11 
    3724 
    3825#define SFI_WRITE_BUFFER_SIZE   4 
Note: See TracChangeset for help on using the changeset viewer.