Changeset 43738


Ignore:
Timestamp:
2014-12-17T15:53:25+01:00 (3 years ago)
Author:
rmilecki
Message:

bcm53xx: backport spi-nor changes and update bcm53xxspiflash

Signed-off-by: Rafał Miłecki <zajec5@…>

Location:
trunk/target/linux/bcm53xx
Files:
5 added
6 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/bcm53xx/patches-3.14/002-mtd-spi-nor-from-3.18.patch

    r43031 r43738  
    11--- a/drivers/mtd/spi-nor/spi-nor.c 
    22+++ b/drivers/mtd/spi-nor/spi-nor.c 
    3 @@ -611,6 +611,7 @@ const struct spi_device_id spi_nor_ids[] 
     3@@ -28,6 +28,8 @@ 
     4  
     5 #define JEDEC_MFR(_jedec_id)   ((_jedec_id) >> 16) 
     6  
     7+static const struct spi_device_id *spi_nor_match_id(const char *name); 
     8+ 
     9 /* 
     10  * Read the status register, returning its value in the location 
     11  * Return the status register value. 
     12@@ -473,7 +475,7 @@ struct flash_info { 
     13  * more nor chips.  This current list focusses on newer chips, which 
     14  * have been converging on command sets which including JEDEC ID. 
     15  */ 
     16-const struct spi_device_id spi_nor_ids[] = { 
     17+static const struct spi_device_id spi_nor_ids[] = { 
     18        /* Atmel -- some are (confusingly) marketed as "DataFlash" */ 
     19        { "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K) }, 
     20        { "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) }, 
     21@@ -611,6 +613,7 @@ const struct spi_device_id spi_nor_ids[] 
    422        { "m25px32-s0", INFO(0x207316,  0, 64 * 1024, 64, SECT_4K) }, 
    523        { "m25px32-s1", INFO(0x206316,  0, 64 * 1024, 64, SECT_4K) }, 
     
    927        /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ 
    1028        { "w25x10", INFO(0xef3011, 0, 64 * 1024,  2,  SECT_4K) }, 
    11 @@ -623,7 +624,6 @@ const struct spi_device_id spi_nor_ids[] 
     29@@ -623,7 +626,6 @@ const struct spi_device_id spi_nor_ids[] 
    1230        { "w25q32dw", INFO(0xef6016, 0, 64 * 1024,  64, SECT_4K) }, 
    1331        { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, 
     
    1735        { "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) }, 
    1836        { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, 
    19 @@ -671,11 +671,6 @@ static const struct spi_device_id *spi_n 
     37@@ -637,7 +639,6 @@ const struct spi_device_id spi_nor_ids[] 
     38        { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, 
     39        { }, 
     40 }; 
     41-EXPORT_SYMBOL_GPL(spi_nor_ids); 
     42  
     43 static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor) 
     44 { 
     45@@ -671,11 +672,6 @@ static const struct spi_device_id *spi_n 
    2046        return ERR_PTR(-ENODEV); 
    2147 } 
     
    2955                        size_t *retlen, u_char *buf) 
    3056 { 
    31 @@ -920,7 +915,6 @@ int spi_nor_scan(struct spi_nor *nor, co 
    32                         enum read_mode mode) 
    33  { 
     57@@ -916,11 +912,10 @@ static int spi_nor_check(struct spi_nor 
     58        return 0; 
     59 } 
     60  
     61-int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id, 
     62-                       enum read_mode mode) 
     63+int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) 
     64 { 
     65+       const struct spi_device_id      *id = NULL; 
    3466        struct flash_info               *info; 
    3567-       struct flash_platform_data      *data; 
     
    3769        struct mtd_info *mtd = nor->mtd; 
    3870        struct device_node *np = dev->of_node; 
    39 @@ -931,34 +925,12 @@ int spi_nor_scan(struct spi_nor *nor, co 
     71@@ -931,34 +926,16 @@ int spi_nor_scan(struct spi_nor *nor, co 
    4072        if (ret) 
    4173                return ret; 
     
    6294-                       dev_warn(dev, "unrecognized id %s\n", data->type); 
    6395-       } 
    64 - 
     96+       id = spi_nor_match_id(name); 
     97+       if (!id) 
     98+               return -ENOENT; 
     99  
    65100        info = (void *)id->driver_data; 
    66101  
     
    73108                        return PTR_ERR(jid); 
    74109                } else if (jid != id) { 
    75 @@ -990,11 +962,8 @@ int spi_nor_scan(struct spi_nor *nor, co 
     110@@ -990,11 +967,8 @@ int spi_nor_scan(struct spi_nor *nor, co 
    76111                write_sr(nor, 0); 
    77112        } 
     
    86121        mtd->writesize = 1; 
    87122        mtd->flags = MTD_CAP_NORFLASH; 
    88 @@ -1018,6 +987,7 @@ int spi_nor_scan(struct spi_nor *nor, co 
     123@@ -1018,6 +992,7 @@ int spi_nor_scan(struct spi_nor *nor, co 
    89124            nor->wait_till_ready == spi_nor_wait_till_ready) 
    90125                nor->wait_till_ready = spi_nor_wait_till_fsr_ready; 
     
    94129        if (info->flags & SECT_4K) { 
    95130                nor->erase_opcode = SPINOR_OP_BE_4K; 
    96 @@ -1025,7 +995,9 @@ int spi_nor_scan(struct spi_nor *nor, co 
     131@@ -1025,7 +1000,9 @@ int spi_nor_scan(struct spi_nor *nor, co 
    97132        } else if (info->flags & SECT_4K_PMC) { 
    98133                nor->erase_opcode = SPINOR_OP_BE_4K_PMC; 
     
    105140                mtd->erasesize = info->sector_size; 
    106141        } 
     142@@ -1141,7 +1118,7 @@ int spi_nor_scan(struct spi_nor *nor, co 
     143 } 
     144 EXPORT_SYMBOL_GPL(spi_nor_scan); 
     145  
     146-const struct spi_device_id *spi_nor_match_id(char *name) 
     147+static const struct spi_device_id *spi_nor_match_id(const char *name) 
     148 { 
     149        const struct spi_device_id *id = spi_nor_ids; 
     150  
     151@@ -1152,7 +1129,6 @@ const struct spi_device_id *spi_nor_matc 
     152        } 
     153        return NULL; 
     154 } 
     155-EXPORT_SYMBOL_GPL(spi_nor_match_id); 
     156  
     157 MODULE_LICENSE("GPL"); 
     158 MODULE_AUTHOR("Huang Shijie <shijie8@gmail.com>"); 
    107159--- a/drivers/mtd/spi-nor/Kconfig 
    108160+++ b/drivers/mtd/spi-nor/Kconfig 
     
    128180        tristate "Freescale Quad SPI controller" 
    129181        depends on ARCH_MXC 
     182--- a/include/linux/mtd/spi-nor.h 
     183+++ b/include/linux/mtd/spi-nor.h 
     184@@ -187,32 +187,17 @@ struct spi_nor { 
     185 /** 
     186  * spi_nor_scan() - scan the SPI NOR 
     187  * @nor:       the spi_nor structure 
     188- * @id:                the spi_device_id provided by the driver 
     189+ * @name:      the chip type name 
     190  * @mode:      the read mode supported by the driver 
     191  * 
     192  * The drivers can use this fuction to scan the SPI NOR. 
     193  * In the scanning, it will try to get all the necessary information to 
     194  * fill the mtd_info{} and the spi_nor{}. 
     195  * 
     196- * The board may assigns a spi_device_id with @id which be used to compared with 
     197- * the spi_device_id detected by the scanning. 
     198+ * The chip type name can be provided through the @name parameter. 
     199  * 
     200  * Return: 0 for success, others for failure. 
     201  */ 
     202-int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id, 
     203-                       enum read_mode mode); 
     204-extern const struct spi_device_id spi_nor_ids[]; 
     205- 
     206-/** 
     207- * spi_nor_match_id() - find the spi_device_id by the name 
     208- * @name:      the name of the spi_device_id 
     209- * 
     210- * The drivers use this function to find the spi_device_id 
     211- * specified by the @name. 
     212- * 
     213- * Return: returns the right spi_device_id pointer on success, 
     214- *         and returns NULL on failure. 
     215- */ 
     216-const struct spi_device_id *spi_nor_match_id(char *name); 
     217+int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode); 
     218  
     219 #endif 
  • trunk/target/linux/bcm53xx/patches-3.14/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch

    r43144 r43738  
    1818 obj-$(CONFIG_SPI_FSL_QUADSPI)  += fsl-quadspi.o 
    1919+obj-$(CONFIG_MTD_SPI_BCM53XXSPIFLASH)  += bcm53xxspiflash.o 
    20 --- /dev/null 
    21 +++ b/drivers/mtd/spi-nor/bcm53xxspiflash.c 
    22 @@ -0,0 +1,241 @@ 
    23 +#include <linux/module.h> 
    24 +#include <linux/delay.h> 
    25 +#include <linux/spi/spi.h> 
    26 +#include <linux/mtd/spi-nor.h> 
    27 +#include <linux/mtd/mtd.h> 
    28 +#include <linux/mtd/cfi.h> 
    29 + 
    30 +static const char * const probes[] = { "bcm47xxpart", NULL }; 
    31 + 
    32 +struct bcm53xxsf { 
    33 +       struct spi_device *spi; 
    34 +       struct mtd_info mtd; 
    35 +       struct spi_nor nor; 
    36 +}; 
    37 + 
    38 +/************************************************** 
    39 + * spi-nor API 
    40 + **************************************************/ 
    41 + 
    42 +static int bcm53xxspiflash_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, 
    43 +                                  int len) 
    44 +{ 
    45 +       struct bcm53xxsf *b53sf = nor->priv; 
    46 + 
    47 +       return spi_write_then_read(b53sf->spi, &opcode, 1, buf, len); 
    48 +} 
    49 + 
    50 +static int bcm53xxspiflash_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, 
    51 +                                    int len, int write_enable) 
    52 +{ 
    53 +       struct bcm53xxsf *b53sf = nor->priv; 
    54 +       u8 *cmd = kzalloc(len + 1, GFP_KERNEL); 
    55 +       int err; 
    56 + 
    57 +       if (!cmd) 
    58 +               return -ENOMEM; 
    59 + 
    60 +       cmd[0] = opcode; 
    61 +       memcpy(&cmd[1], buf, len); 
    62 +       err = spi_write(b53sf->spi, cmd, len + 1); 
    63 + 
    64 +       kfree(cmd); 
    65 + 
    66 +       return err; 
    67 +} 
    68 + 
    69 +static int bcm53xxspiflash_read(struct spi_nor *nor, loff_t from, size_t len, 
    70 +                               size_t *retlen, u_char *buf) 
    71 +{ 
    72 +       struct bcm53xxsf *b53sf = nor->priv; 
    73 +       struct spi_message m; 
    74 +       struct spi_transfer t[2] = { { 0 }, { 0 } }; 
    75 +       unsigned char cmd[5]; 
    76 +       int cmd_len = 0; 
    77 +       int err; 
    78 + 
    79 +       spi_message_init(&m); 
    80 + 
    81 +       cmd[cmd_len++] = SPINOR_OP_READ; 
    82 +       if (b53sf->mtd.size > 0x1000000) 
    83 +               cmd[cmd_len++] = (from & 0xFF000000) >> 24; 
    84 +       cmd[cmd_len++] = (from & 0x00FF0000) >> 16; 
    85 +       cmd[cmd_len++] = (from & 0x0000FF00) >> 8; 
    86 +       cmd[cmd_len++] = (from & 0x000000FF) >> 0; 
    87 + 
    88 +       t[0].tx_buf = cmd; 
    89 +       t[0].len = cmd_len; 
    90 +       spi_message_add_tail(&t[0], &m); 
    91 + 
    92 +       t[1].rx_buf = buf; 
    93 +       t[1].len = len; 
    94 +       spi_message_add_tail(&t[1], &m); 
    95 + 
    96 +       err = spi_sync(b53sf->spi, &m); 
    97 +       if (err) 
    98 +               return err; 
    99 + 
    100 +       if (retlen && m.actual_length > cmd_len) 
    101 +               *retlen = m.actual_length - cmd_len; 
    102 + 
    103 +       return 0; 
    104 +} 
    105 + 
    106 +static void bcm53xxspiflash_write(struct spi_nor *nor, loff_t to, size_t len, 
    107 +                                 size_t *retlen, const u_char *buf) 
    108 +{ 
    109 +       struct bcm53xxsf *b53sf = nor->priv; 
    110 +       struct spi_message m; 
    111 +       struct spi_transfer t = { 0 }; 
    112 +       u8 *cmd = kzalloc(len + 5, GFP_KERNEL); 
    113 +       int cmd_len = 0; 
    114 +       int err; 
    115 + 
    116 +       if (!cmd) 
    117 +               return; 
    118 + 
    119 +       spi_message_init(&m); 
    120 + 
    121 +       cmd[cmd_len++] = nor->program_opcode; 
    122 +       if (b53sf->mtd.size > 0x1000000) 
    123 +               cmd[cmd_len++] = (to & 0xFF000000) >> 24; 
    124 +       cmd[cmd_len++] = (to & 0x00FF0000) >> 16; 
    125 +       cmd[cmd_len++] = (to & 0x0000FF00) >> 8; 
    126 +       cmd[cmd_len++] = (to & 0x000000FF) >> 0; 
    127 +       memcpy(&cmd[cmd_len], buf, len); 
    128 + 
    129 +       t.tx_buf = cmd; 
    130 +       t.len = cmd_len + len; 
    131 +       spi_message_add_tail(&t, &m); 
    132 + 
    133 +       err = spi_sync(b53sf->spi, &m); 
    134 +       if (err) 
    135 +               goto out; 
    136 + 
    137 +       if (retlen && m.actual_length > cmd_len) 
    138 +               *retlen += m.actual_length - cmd_len; 
    139 + 
    140 +out: 
    141 +       kfree(cmd); 
    142 +} 
    143 + 
    144 +static int bcm53xxspiflash_erase(struct spi_nor *nor, loff_t offs) 
    145 +{ 
    146 +       struct bcm53xxsf *b53sf = nor->priv; 
    147 +       unsigned char cmd[5]; 
    148 +       int i; 
    149 + 
    150 +       i = 0; 
    151 +       cmd[i++] = nor->erase_opcode; 
    152 +       if (b53sf->mtd.size > 0x1000000) 
    153 +               cmd[i++] = (offs & 0xFF000000) >> 24; 
    154 +       cmd[i++] = ((offs & 0x00FF0000) >> 16); 
    155 +       cmd[i++] = ((offs & 0x0000FF00) >> 8); 
    156 +       cmd[i++] = ((offs & 0x000000FF) >> 0); 
    157 + 
    158 +       return spi_write(b53sf->spi, cmd, i); 
    159 +} 
    160 + 
    161 +static const struct spi_device_id *bcm53xxspiflash_read_id(struct spi_nor *nor) 
    162 +{ 
    163 +       struct bcm53xxsf *b53sf = nor->priv; 
    164 +       struct device *dev = &b53sf->spi->dev; 
    165 +       const struct spi_device_id *id; 
    166 +       unsigned char cmd[4]; 
    167 +       unsigned char resp[2]; 
    168 +       char *name = NULL; 
    169 +       int err; 
    170 + 
    171 +       /* SST and Winbond/NexFlash specific command */ 
    172 +       cmd[0] = 0x90; /* Read Manufacturer / Device ID */ 
    173 +       cmd[1] = 0; 
    174 +       cmd[2] = 0; 
    175 +       cmd[3] = 0; 
    176 +       err = spi_write_then_read(b53sf->spi, cmd, 4, resp, 2); 
    177 +       if (err < 0) { 
    178 +               dev_err(dev, "error reading SPI flash id\n"); 
    179 +               return ERR_PTR(-EBUSY); 
    180 +       } 
    181 +       switch (resp[0]) { 
    182 +       case 0xef: /* Winbond/NexFlash */ 
    183 +               switch (resp[1]) { 
    184 +               case 0x17: 
    185 +                       name = "w25q128"; 
    186 +                       break; 
    187 +               } 
    188 +               if (!name) { 
    189 +                       dev_err(dev, "Unknown Winbond/NexFlash flash: %02X %02X\n", 
    190 +                               resp[0], resp[1]); 
    191 +                       return ERR_PTR(-ENOTSUPP); 
    192 +               } 
    193 +               goto found_name; 
    194 +       } 
    195 + 
    196 +       /* TODO: Try more ID commands */ 
    197 + 
    198 +       return ERR_PTR(-ENODEV); 
    199 + 
    200 +found_name: 
    201 +       id = spi_nor_match_id(name); 
    202 +       if (!id) { 
    203 +               dev_err(dev, "No matching entry for %s flash\n", name); 
    204 +               return ERR_PTR(-ENOENT); 
    205 +       } 
    206 + 
    207 +       return id; 
    208 +} 
    209 + 
    210 +/************************************************** 
    211 + * SPI driver 
    212 + **************************************************/ 
    213 + 
    214 +static int bcm53xxspiflash_probe(struct spi_device *spi) 
    215 +{ 
    216 +       struct bcm53xxsf *b53sf; 
    217 +       int err; 
    218 + 
    219 +       b53sf = devm_kzalloc(&spi->dev, sizeof(*b53sf), GFP_KERNEL); 
    220 +       if (!b53sf) 
    221 +               return -ENOMEM; 
    222 +       spi_set_drvdata(spi, b53sf); 
    223 + 
    224 +       b53sf->spi = spi; 
    225 + 
    226 +       b53sf->mtd.priv = &b53sf->nor; 
    227 + 
    228 +       b53sf->nor.mtd = &b53sf->mtd; 
    229 +       b53sf->nor.dev = &spi->dev; 
    230 +       b53sf->nor.read_reg = bcm53xxspiflash_read_reg; 
    231 +       b53sf->nor.write_reg = bcm53xxspiflash_write_reg; 
    232 +       b53sf->nor.read = bcm53xxspiflash_read; 
    233 +       b53sf->nor.write = bcm53xxspiflash_write; 
    234 +       b53sf->nor.erase = bcm53xxspiflash_erase; 
    235 +       b53sf->nor.read_id = bcm53xxspiflash_read_id; 
    236 +       b53sf->nor.priv = b53sf; 
    237 + 
    238 +       err = spi_nor_scan(&b53sf->nor, NULL, SPI_NOR_NORMAL); 
    239 +       if (err) 
    240 +               return err; 
    241 + 
    242 +       err = mtd_device_parse_register(&b53sf->mtd, probes, NULL, NULL, 0); 
    243 +       if (err) 
    244 +               return err; 
    245 + 
    246 +       return 0; 
    247 +} 
    248 + 
    249 +static int bcm53xxspiflash_remove(struct spi_device *spi) 
    250 +{ 
    251 +       return 0; 
    252 +} 
    253 + 
    254 +static struct spi_driver bcm53xxspiflash_driver = { 
    255 +       .driver = { 
    256 +               .name   = "bcm53xxspiflash", 
    257 +               .owner  = THIS_MODULE, 
    258 +       }, 
    259 +       .probe          = bcm53xxspiflash_probe, 
    260 +       .remove         = bcm53xxspiflash_remove, 
    261 +}; 
    262 + 
    263 +module_spi_driver(bcm53xxspiflash_driver); 
  • trunk/target/linux/bcm53xx/patches-3.18/404-mtd-bcm53xxspiflash-new-driver-for-SPI-flahes-on-Bro.patch

    r43229 r43738  
    1818 obj-$(CONFIG_SPI_FSL_QUADSPI)  += fsl-quadspi.o 
    1919+obj-$(CONFIG_MTD_SPI_BCM53XXSPIFLASH)  += bcm53xxspiflash.o 
    20 --- /dev/null 
    21 +++ b/drivers/mtd/spi-nor/bcm53xxspiflash.c 
    22 @@ -0,0 +1,241 @@ 
    23 +#include <linux/module.h> 
    24 +#include <linux/delay.h> 
    25 +#include <linux/spi/spi.h> 
    26 +#include <linux/mtd/spi-nor.h> 
    27 +#include <linux/mtd/mtd.h> 
    28 +#include <linux/mtd/cfi.h> 
    29 + 
    30 +static const char * const probes[] = { "bcm47xxpart", NULL }; 
    31 + 
    32 +struct bcm53xxsf { 
    33 +       struct spi_device *spi; 
    34 +       struct mtd_info mtd; 
    35 +       struct spi_nor nor; 
    36 +}; 
    37 + 
    38 +/************************************************** 
    39 + * spi-nor API 
    40 + **************************************************/ 
    41 + 
    42 +static int bcm53xxspiflash_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, 
    43 +                                  int len) 
    44 +{ 
    45 +       struct bcm53xxsf *b53sf = nor->priv; 
    46 + 
    47 +       return spi_write_then_read(b53sf->spi, &opcode, 1, buf, len); 
    48 +} 
    49 + 
    50 +static int bcm53xxspiflash_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, 
    51 +                                    int len, int write_enable) 
    52 +{ 
    53 +       struct bcm53xxsf *b53sf = nor->priv; 
    54 +       u8 *cmd = kzalloc(len + 1, GFP_KERNEL); 
    55 +       int err; 
    56 + 
    57 +       if (!cmd) 
    58 +               return -ENOMEM; 
    59 + 
    60 +       cmd[0] = opcode; 
    61 +       memcpy(&cmd[1], buf, len); 
    62 +       err = spi_write(b53sf->spi, cmd, len + 1); 
    63 + 
    64 +       kfree(cmd); 
    65 + 
    66 +       return err; 
    67 +} 
    68 + 
    69 +static int bcm53xxspiflash_read(struct spi_nor *nor, loff_t from, size_t len, 
    70 +                               size_t *retlen, u_char *buf) 
    71 +{ 
    72 +       struct bcm53xxsf *b53sf = nor->priv; 
    73 +       struct spi_message m; 
    74 +       struct spi_transfer t[2] = { { 0 }, { 0 } }; 
    75 +       unsigned char cmd[5]; 
    76 +       int cmd_len = 0; 
    77 +       int err; 
    78 + 
    79 +       spi_message_init(&m); 
    80 + 
    81 +       cmd[cmd_len++] = SPINOR_OP_READ; 
    82 +       if (b53sf->mtd.size > 0x1000000) 
    83 +               cmd[cmd_len++] = (from & 0xFF000000) >> 24; 
    84 +       cmd[cmd_len++] = (from & 0x00FF0000) >> 16; 
    85 +       cmd[cmd_len++] = (from & 0x0000FF00) >> 8; 
    86 +       cmd[cmd_len++] = (from & 0x000000FF) >> 0; 
    87 + 
    88 +       t[0].tx_buf = cmd; 
    89 +       t[0].len = cmd_len; 
    90 +       spi_message_add_tail(&t[0], &m); 
    91 + 
    92 +       t[1].rx_buf = buf; 
    93 +       t[1].len = len; 
    94 +       spi_message_add_tail(&t[1], &m); 
    95 + 
    96 +       err = spi_sync(b53sf->spi, &m); 
    97 +       if (err) 
    98 +               return err; 
    99 + 
    100 +       if (retlen && m.actual_length > cmd_len) 
    101 +               *retlen = m.actual_length - cmd_len; 
    102 + 
    103 +       return 0; 
    104 +} 
    105 + 
    106 +static void bcm53xxspiflash_write(struct spi_nor *nor, loff_t to, size_t len, 
    107 +                                 size_t *retlen, const u_char *buf) 
    108 +{ 
    109 +       struct bcm53xxsf *b53sf = nor->priv; 
    110 +       struct spi_message m; 
    111 +       struct spi_transfer t = { 0 }; 
    112 +       u8 *cmd = kzalloc(len + 5, GFP_KERNEL); 
    113 +       int cmd_len = 0; 
    114 +       int err; 
    115 + 
    116 +       if (!cmd) 
    117 +               return; 
    118 + 
    119 +       spi_message_init(&m); 
    120 + 
    121 +       cmd[cmd_len++] = nor->program_opcode; 
    122 +       if (b53sf->mtd.size > 0x1000000) 
    123 +               cmd[cmd_len++] = (to & 0xFF000000) >> 24; 
    124 +       cmd[cmd_len++] = (to & 0x00FF0000) >> 16; 
    125 +       cmd[cmd_len++] = (to & 0x0000FF00) >> 8; 
    126 +       cmd[cmd_len++] = (to & 0x000000FF) >> 0; 
    127 +       memcpy(&cmd[cmd_len], buf, len); 
    128 + 
    129 +       t.tx_buf = cmd; 
    130 +       t.len = cmd_len + len; 
    131 +       spi_message_add_tail(&t, &m); 
    132 + 
    133 +       err = spi_sync(b53sf->spi, &m); 
    134 +       if (err) 
    135 +               goto out; 
    136 + 
    137 +       if (retlen && m.actual_length > cmd_len) 
    138 +               *retlen += m.actual_length - cmd_len; 
    139 + 
    140 +out: 
    141 +       kfree(cmd); 
    142 +} 
    143 + 
    144 +static int bcm53xxspiflash_erase(struct spi_nor *nor, loff_t offs) 
    145 +{ 
    146 +       struct bcm53xxsf *b53sf = nor->priv; 
    147 +       unsigned char cmd[5]; 
    148 +       int i; 
    149 + 
    150 +       i = 0; 
    151 +       cmd[i++] = nor->erase_opcode; 
    152 +       if (b53sf->mtd.size > 0x1000000) 
    153 +               cmd[i++] = (offs & 0xFF000000) >> 24; 
    154 +       cmd[i++] = ((offs & 0x00FF0000) >> 16); 
    155 +       cmd[i++] = ((offs & 0x0000FF00) >> 8); 
    156 +       cmd[i++] = ((offs & 0x000000FF) >> 0); 
    157 + 
    158 +       return spi_write(b53sf->spi, cmd, i); 
    159 +} 
    160 + 
    161 +static const struct spi_device_id *bcm53xxspiflash_read_id(struct spi_nor *nor) 
    162 +{ 
    163 +       struct bcm53xxsf *b53sf = nor->priv; 
    164 +       struct device *dev = &b53sf->spi->dev; 
    165 +       const struct spi_device_id *id; 
    166 +       unsigned char cmd[4]; 
    167 +       unsigned char resp[2]; 
    168 +       char *name = NULL; 
    169 +       int err; 
    170 + 
    171 +       /* SST and Winbond/NexFlash specific command */ 
    172 +       cmd[0] = 0x90; /* Read Manufacturer / Device ID */ 
    173 +       cmd[1] = 0; 
    174 +       cmd[2] = 0; 
    175 +       cmd[3] = 0; 
    176 +       err = spi_write_then_read(b53sf->spi, cmd, 4, resp, 2); 
    177 +       if (err < 0) { 
    178 +               dev_err(dev, "error reading SPI flash id\n"); 
    179 +               return ERR_PTR(-EBUSY); 
    180 +       } 
    181 +       switch (resp[0]) { 
    182 +       case 0xef: /* Winbond/NexFlash */ 
    183 +               switch (resp[1]) { 
    184 +               case 0x17: 
    185 +                       name = "w25q128"; 
    186 +                       break; 
    187 +               } 
    188 +               if (!name) { 
    189 +                       dev_err(dev, "Unknown Winbond/NexFlash flash: %02X %02X\n", 
    190 +                               resp[0], resp[1]); 
    191 +                       return ERR_PTR(-ENOTSUPP); 
    192 +               } 
    193 +               goto found_name; 
    194 +       } 
    195 + 
    196 +       /* TODO: Try more ID commands */ 
    197 + 
    198 +       return ERR_PTR(-ENODEV); 
    199 + 
    200 +found_name: 
    201 +//     id = spi_nor_match_id(name); 
    202 +//     if (!id) { 
    203 +//             dev_err(dev, "No matching entry for %s flash\n", name); 
    204 +//             return ERR_PTR(-ENOENT); 
    205 +//     } 
    206 + 
    207 +       return id; 
    208 +} 
    209 + 
    210 +/************************************************** 
    211 + * SPI driver 
    212 + **************************************************/ 
    213 + 
    214 +static int bcm53xxspiflash_probe(struct spi_device *spi) 
    215 +{ 
    216 +       struct bcm53xxsf *b53sf; 
    217 +       int err; 
    218 + 
    219 +       b53sf = devm_kzalloc(&spi->dev, sizeof(*b53sf), GFP_KERNEL); 
    220 +       if (!b53sf) 
    221 +               return -ENOMEM; 
    222 +       spi_set_drvdata(spi, b53sf); 
    223 + 
    224 +       b53sf->spi = spi; 
    225 + 
    226 +       b53sf->mtd.priv = &b53sf->nor; 
    227 + 
    228 +       b53sf->nor.mtd = &b53sf->mtd; 
    229 +       b53sf->nor.dev = &spi->dev; 
    230 +       b53sf->nor.read_reg = bcm53xxspiflash_read_reg; 
    231 +       b53sf->nor.write_reg = bcm53xxspiflash_write_reg; 
    232 +       b53sf->nor.read = bcm53xxspiflash_read; 
    233 +       b53sf->nor.write = bcm53xxspiflash_write; 
    234 +       b53sf->nor.erase = bcm53xxspiflash_erase; 
    235 +       b53sf->nor.read_id = bcm53xxspiflash_read_id; 
    236 +       b53sf->nor.priv = b53sf; 
    237 + 
    238 +       err = spi_nor_scan(&b53sf->nor, "w25q128", SPI_NOR_NORMAL); 
    239 +       if (err) 
    240 +               return err; 
    241 + 
    242 +       err = mtd_device_parse_register(&b53sf->mtd, probes, NULL, NULL, 0); 
    243 +       if (err) 
    244 +               return err; 
    245 + 
    246 +       return 0; 
    247 +} 
    248 + 
    249 +static int bcm53xxspiflash_remove(struct spi_device *spi) 
    250 +{ 
    251 +       return 0; 
    252 +} 
    253 + 
    254 +static struct spi_driver bcm53xxspiflash_driver = { 
    255 +       .driver = { 
    256 +               .name   = "bcm53xxspiflash", 
    257 +               .owner  = THIS_MODULE, 
    258 +       }, 
    259 +       .probe          = bcm53xxspiflash_probe, 
    260 +       .remove         = bcm53xxspiflash_remove, 
    261 +}; 
    262 + 
    263 +module_spi_driver(bcm53xxspiflash_driver); 
Note: See TracChangeset for help on using the changeset viewer.