[U-Boot] [PATCH v3 2/8] sf: describe all SPI flash commands with 'struct spi_flash_command'

Jagan Teki jagannadh.teki at gmail.com
Wed Aug 30 14:03:30 UTC 2017


On Tue, Jul 25, 2017 at 12:30 PM, Wenyou Yang <wenyou.yang at microchip.com> wrote:
> From: Cyrille Pitchen <cyrille.pitchen at atmel.com>
>
> Now that the SPI sub-system API has been extended with
> 'struct spi_flash_command' and spi_is_flash_command_supported() /
> spi_exec_flash_command() functions, we update the SPI FLASH sub-system to
> use this new API.
>
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
> Signed-off-by: Wenyou Yang <wenyou.yang at microchip.com>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
>  drivers/mtd/spi/sf.c           |  78 +++++++++++++----
>  drivers/mtd/spi/sf_dataflash.c | 119 +++++++++++++-------------
>  drivers/mtd/spi/sf_internal.h  |  24 +++---
>  drivers/mtd/spi/spi_flash.c    | 184 +++++++++++++++++++++++------------------
>  4 files changed, 236 insertions(+), 169 deletions(-)
>
> diff --git a/drivers/mtd/spi/sf.c b/drivers/mtd/spi/sf.c
> index d5e175ca00..6178b0aa98 100644
> --- a/drivers/mtd/spi/sf.c
> +++ b/drivers/mtd/spi/sf.c
> @@ -9,46 +9,88 @@
>
>  #include <common.h>
>  #include <spi.h>
> +#include <spi_flash.h>
>
> -static int spi_flash_read_write(struct spi_slave *spi,
> -                               const u8 *cmd, size_t cmd_len,
> -                               const u8 *data_out, u8 *data_in,
> -                               size_t data_len)
> +#include "sf_internal.h"
> +
> +static void spi_flash_addr(u32 addr, u8 addr_len, u8 *cmd_buf)
>  {
> +       u8 i;
> +
> +       for (i = 0; i < addr_len; i++)
> +               cmd_buf[i] = addr >> ((addr_len - 1 - i) * 8);
> +}
> +
> +static u8 spi_compute_num_dummy_bytes(enum spi_flash_protocol proto,
> +                                     u8 num_dummy_clock_cycles)
> +{
> +       int shift = fls(spi_flash_protocol_get_addr_nbits(proto)) - 1;
> +
> +       if (shift < 0)
> +               shift = 0;
> +       return (num_dummy_clock_cycles << shift) >> 3;
> +}
> +
> +static int spi_flash_exec(struct spi_flash *flash,
> +                         const struct spi_flash_command *cmd)
> +{
> +       struct spi_slave *spi = flash->spi;
> +       u8 cmd_buf[SPI_FLASH_CMD_LEN];
> +       size_t cmd_len, num_dummy_bytes;
>         unsigned long flags = SPI_XFER_BEGIN;
>         int ret;
>
> -       if (data_len == 0)
> +       if (spi_is_flash_command_supported(spi, cmd))
> +               return spi_exec_flash_command(spi, cmd);
> +
> +       if (cmd->data_len == 0)
>                 flags |= SPI_XFER_END;
>
> -       ret = spi_xfer(spi, cmd_len * 8, cmd, NULL, flags);
> +       cmd_buf[0] = cmd->inst;
> +       spi_flash_addr(cmd->addr, cmd->addr_len, cmd_buf + 1);
> +       cmd_len = 1 + cmd->addr_len;
> +
> +       num_dummy_bytes = spi_compute_num_dummy_bytes(cmd->proto,
> +                                                     cmd->num_mode_cycles +
> +                                                     cmd->num_wait_states);
> +       memset(cmd_buf + cmd_len, 0xff, num_dummy_bytes);
> +       cmd_len += num_dummy_bytes;
> +
> +       ret = spi_xfer(spi, cmd_len * 8, cmd_buf, NULL, flags);
>         if (ret) {
>                 debug("SF: Failed to send command (%zu bytes): %d\n",
>                       cmd_len, ret);
> -       } else if (data_len != 0) {
> -               ret = spi_xfer(spi, data_len * 8, data_out, data_in,
> -                                       SPI_XFER_END);
> +       } else if (cmd->data_len != 0) {
> +               ret = spi_xfer(spi, cmd->data_len * 8,
> +                              cmd->tx_data, cmd->rx_data,
> +                              SPI_XFER_END);
>                 if (ret)
>                         debug("SF: Failed to transfer %zu bytes of data: %d\n",
> -                             data_len, ret);
> +                             cmd->data_len, ret);
>         }
>
>         return ret;
>  }
>
> -int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd,
> -               size_t cmd_len, void *data, size_t data_len)
> +int spi_flash_cmd_read(struct spi_flash *flash,
> +                      const struct spi_flash_command *cmd)
>  {
> -       return spi_flash_read_write(spi, cmd, cmd_len, NULL, data, data_len);
> +       return spi_flash_exec(flash, cmd);
>  }
>
> -int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len)
> +int spi_flash_cmd(struct spi_flash *flash, u8 instr, void *response, size_t len)
>  {
> -       return spi_flash_cmd_read(spi, &cmd, 1, response, len);
> +       struct spi_flash_command cmd;
> +       u8 flags = (response && len) ? SPI_FCMD_READ_REG : SPI_FCMD_WRITE_REG;
> +
> +       spi_flash_command_init(&cmd, instr, 0, flags);
> +       cmd.data_len = len;
> +       cmd.rx_data = response;
> +       return spi_flash_exec(flash, &cmd);
>  }
>
> -int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
> -               const void *data, size_t data_len)
> +int spi_flash_cmd_write(struct spi_flash *flash,
> +                       const struct spi_flash_command *cmd)
>  {
> -       return spi_flash_read_write(spi, cmd, cmd_len, data, NULL, data_len);
> +       return spi_flash_exec(flash, cmd);
>  }
> diff --git a/drivers/mtd/spi/sf_dataflash.c b/drivers/mtd/spi/sf_dataflash.c
> index bcddfa0755..b2166ad4e5 100644
> --- a/drivers/mtd/spi/sf_dataflash.c
> +++ b/drivers/mtd/spi/sf_dataflash.c
> @@ -73,7 +73,7 @@ struct dataflash {
>  };
>
>  /* Return the status of the DataFlash device */
> -static inline int dataflash_status(struct spi_slave *spi)
> +static inline int dataflash_status(struct spi_flash *spi_flash)
>  {
>         int ret;
>         u8 status;
> @@ -81,7 +81,7 @@ static inline int dataflash_status(struct spi_slave *spi)
>          * NOTE:  at45db321c over 25 MHz wants to write
>          * a dummy byte after the opcode...
>          */
> -       ret = spi_flash_cmd(spi, OP_READ_STATUS, &status, 1);
> +       ret = spi_flash_cmd(spi_flash, OP_READ_STATUS, &status, 1);
>         return ret ? -EIO : status;
>  }
>
> @@ -90,7 +90,7 @@ static inline int dataflash_status(struct spi_slave *spi)
>   * This usually takes 5-20 msec or so; more for sector erase.
>   * ready: return > 0
>   */
> -static int dataflash_waitready(struct spi_slave *spi)
> +static int dataflash_waitready(struct spi_flash *spi_flash)
>  {
>         int status;
>         int timeout = 2 * CONFIG_SYS_HZ;
> @@ -98,7 +98,7 @@ static int dataflash_waitready(struct spi_slave *spi)
>
>         timebase = get_timer(0);
>         do {
> -               status = dataflash_status(spi);
> +               status = dataflash_status(spi_flash);
>                 if (status < 0)
>                         status = 0;
>
> @@ -114,11 +114,11 @@ static int dataflash_waitready(struct spi_slave *spi)
>  /* Erase pages of flash */
>  static int spi_dataflash_erase(struct udevice *dev, u32 offset, size_t len)
>  {
> +       struct spi_flash_command        cmd;
>         struct dataflash        *dataflash;
>         struct spi_flash        *spi_flash;
>         struct spi_slave        *spi;
>         unsigned                blocksize;
> -       uint8_t                 *command;
>         uint32_t                rem;
>         int                     status;
>
> @@ -128,9 +128,6 @@ static int spi_dataflash_erase(struct udevice *dev, u32 offset, size_t len)
>
>         blocksize = spi_flash->page_size << 3;
>
> -       memset(dataflash->command, 0 , sizeof(dataflash->command));
> -       command = dataflash->command;
> -
>         debug("%s: erase addr=0x%x len 0x%x\n", dev->name, offset, len);
>
>         div_u64_rem(len, spi_flash->page_size, &rem);
> @@ -146,6 +143,8 @@ static int spi_dataflash_erase(struct udevice *dev, u32 offset, size_t len)
>                 return status;
>         }
>
> +       spi_flash_command_init(&cmd, OP_ERASE_BLOCK, SPI_FLASH_3B_ADDR_LEN,
> +                              SPI_FCMD_ERASE);
>         while (len > 0) {
>                 unsigned int    pageaddr;
>                 int             do_block;
> @@ -157,23 +156,24 @@ static int spi_dataflash_erase(struct udevice *dev, u32 offset, size_t len)
>                 do_block = (pageaddr & 0x7) == 0 && len >= blocksize;
>                 pageaddr = pageaddr << dataflash->page_offset;
>
> -               command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE;
> -               command[1] = (uint8_t)(pageaddr >> 16);
> -               command[2] = (uint8_t)(pageaddr >> 8);
> -               command[3] = 0;
> +               cmd.inst = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE;
> +               cmd.addr = pageaddr & 0x00FFFF00;
>
>                 debug("%s ERASE %s: (%x) %x %x %x [%d]\n",
>                       dev->name, do_block ? "block" : "page",
> -                     command[0], command[1], command[2], command[3],
> +                     cmd.inst,
> +                     (cmd.addr >> 16) & 0xff,
> +                     (cmd.addr >>  8) & 0xff,
> +                     (cmd.addr >>  0) & 0xff,
>                       pageaddr);
>
> -               status = spi_flash_cmd_write(spi, command, 4, NULL, 0);
> +               status = spi_flash_cmd_write(spi_flash, &cmd);
>                 if (status < 0) {
>                         debug("%s: erase send command error!\n", dev->name);
>                         return -EIO;
>                 }
>
> -               status = dataflash_waitready(spi);
> +               status = dataflash_waitready(spi_flash);
>                 if (status < 0) {
>                         debug("%s: erase waitready error!\n", dev->name);
>                         return status;
> @@ -202,23 +202,18 @@ static int spi_dataflash_erase(struct udevice *dev, u32 offset, size_t len)
>  static int spi_dataflash_read(struct udevice *dev, u32 offset, size_t len,
>                               void *buf)
>  {
> +       struct spi_flash_command        cmd;
>         struct dataflash        *dataflash;
>         struct spi_flash        *spi_flash;
>         struct spi_slave        *spi;
>         unsigned int            addr;
> -       uint8_t                 *command;
>         int                     status;
>
>         dataflash = dev_get_priv(dev);
>         spi_flash = dev_get_uclass_priv(dev);
>         spi = spi_flash->spi;
>
> -       memset(dataflash->command, 0 , sizeof(dataflash->command));
> -       command = dataflash->command;
> -
> -       debug("%s: erase addr=0x%x len 0x%x\n", dev->name, offset, len);
> -       debug("READ: (%x) %x %x %x\n",
> -             command[0], command[1], command[2], command[3]);
> +       debug("%s: read addr=0x%x len 0x%x\n", dev->name, offset, len);
>
>         /* Calculate flash page/byte address */
>         addr = (((unsigned)offset / spi_flash->page_size)
> @@ -236,13 +231,15 @@ static int spi_dataflash_read(struct udevice *dev, u32 offset, size_t len,
>          * the peak rate available.  Some chips support commands with
>          * fewer "don't care" bytes.  Both buffers stay unchanged.
>          */
> -       command[0] = OP_READ_CONTINUOUS;
> -       command[1] = (uint8_t)(addr >> 16);
> -       command[2] = (uint8_t)(addr >> 8);
> -       command[3] = (uint8_t)(addr >> 0);
> +       spi_flash_command_init(&cmd, OP_READ_CONTINUOUS, SPI_FLASH_3B_ADDR_LEN,
> +                              SPI_FCMD_READ);
> +       cmd.addr = addr;
> +       cmd.num_wait_states = 4 * 8; /* 4 "don't care" bytes */
> +       cmd.data_len = len;
> +       cmd.rx_data = buf;
>
>         /* plus 4 "don't care" bytes, command len: 4 + 4 "don't care" bytes */
> -       status = spi_flash_cmd_read(spi, command, 8, buf, len);
> +       status = spi_flash_cmd_read(spi_flash, &cmd);
>
>         spi_release_bus(spi);
>
> @@ -258,10 +255,10 @@ static int spi_dataflash_read(struct udevice *dev, u32 offset, size_t len,
>  int spi_dataflash_write(struct udevice *dev, u32 offset, size_t len,
>                         const void *buf)
>  {
> +       struct spi_flash_command        cmd;
>         struct dataflash        *dataflash;
>         struct spi_flash        *spi_flash;
>         struct spi_slave        *spi;
> -       uint8_t                 *command;
>         unsigned int            pageaddr, addr, to, writelen;
>         size_t                  remaining = len;
>         u_char                  *writebuf = (u_char *)buf;
> @@ -271,9 +268,6 @@ int spi_dataflash_write(struct udevice *dev, u32 offset, size_t len,
>         spi_flash = dev_get_uclass_priv(dev);
>         spi = spi_flash->spi;
>
> -       memset(dataflash->command, 0 , sizeof(dataflash->command));
> -       command = dataflash->command;
> -
>         debug("%s: write 0x%x..0x%x\n", dev->name, offset, (offset + len));
>
>         pageaddr = ((unsigned)offset / spi_flash->page_size);
> @@ -289,6 +283,8 @@ int spi_dataflash_write(struct udevice *dev, u32 offset, size_t len,
>                 return status;
>         }
>
> +       spi_flash_command_init(&cmd, OP_TRANSFER_BUF1, SPI_FLASH_3B_ADDR_LEN,
> +                              SPI_FCMD_WRITE);
>         while (remaining > 0) {
>                 debug("write @ %d:%d len=%d\n", pageaddr, to, writelen);
>
> @@ -313,22 +309,25 @@ int spi_dataflash_write(struct udevice *dev, u32 offset, size_t len,
>
>                 /* (1) Maybe transfer partial page to Buffer1 */
>                 if (writelen != spi_flash->page_size) {
> -                       command[0] = OP_TRANSFER_BUF1;
> -                       command[1] = (addr & 0x00FF0000) >> 16;
> -                       command[2] = (addr & 0x0000FF00) >> 8;
> -                       command[3] = 0;
> +                       cmd.inst = OP_TRANSFER_BUF1;
> +                       cmd.addr = (addr & 0x00FFFF00);
> +                       cmd.data_len = 0;
> +                       cmd.tx_data = NULL;
>
>                         debug("TRANSFER: (%x) %x %x %x\n",
> -                             command[0], command[1], command[2], command[3]);
> +                             cmd.inst,
> +                             (cmd.addr >> 16) & 0xff,
> +                             (cmd.addr >>  8) & 0xff,
> +                             (cmd.addr >>  0) & 0xff);
>
> -                       status = spi_flash_cmd_write(spi, command, 4, NULL, 0);
> +                       status = spi_flash_cmd_write(spi_flash, &cmd);
>                         if (status < 0) {
>                                 debug("%s: write(<pagesize) command error!\n",
>                                       dev->name);
>                                 return -EIO;
>                         }
>
> -                       status = dataflash_waitready(spi);
> +                       status = dataflash_waitready(spi_flash);
>                         if (status < 0) {
>                                 debug("%s: write(<pagesize) waitready error!\n",
>                                       dev->name);
> @@ -338,22 +337,24 @@ int spi_dataflash_write(struct udevice *dev, u32 offset, size_t len,
>
>                 /* (2) Program full page via Buffer1 */
>                 addr += to;
> -               command[0] = OP_PROGRAM_VIA_BUF1;
> -               command[1] = (addr & 0x00FF0000) >> 16;
> -               command[2] = (addr & 0x0000FF00) >> 8;
> -               command[3] = (addr & 0x000000FF);
> +               cmd.inst = OP_PROGRAM_VIA_BUF1;
> +               cmd.addr = addr;
> +               cmd.data_len = writelen;
> +               cmd.tx_data = writebuf;
>
>                 debug("PROGRAM: (%x) %x %x %x\n",
> -                     command[0], command[1], command[2], command[3]);
> +                     cmd.inst,
> +                     (cmd.addr >> 16) & 0xff,
> +                     (cmd.addr >>  8) & 0xff,
> +                     (cmd.addr >>  0) & 0xff);
>
> -               status = spi_flash_cmd_write(spi, command,
> -                                            4, writebuf, writelen);
> +               status = spi_flash_cmd_write(spi_flash, &cmd);
>                 if (status < 0) {
>                         debug("%s: write send command error!\n", dev->name);
>                         return -EIO;
>                 }
>
> -               status = dataflash_waitready(spi);
> +               status = dataflash_waitready(spi_flash);
>                 if (status < 0) {
>                         debug("%s: write waitready error!\n", dev->name);
>                         return status;
> @@ -362,16 +363,18 @@ int spi_dataflash_write(struct udevice *dev, u32 offset, size_t len,
>  #ifdef CONFIG_SPI_DATAFLASH_WRITE_VERIFY
>                 /* (3) Compare to Buffer1 */
>                 addr = pageaddr << dataflash->page_offset;
> -               command[0] = OP_COMPARE_BUF1;
> -               command[1] = (addr & 0x00FF0000) >> 16;
> -               command[2] = (addr & 0x0000FF00) >> 8;
> -               command[3] = 0;
> +               cmd.inst = OP_COMPARE_BUF1;
> +               cmd.addr = addr & 0x00FFFF00;
> +               cmd.data_len = writelen;
> +               cmd.tx_data = writebuf;
>
>                 debug("COMPARE: (%x) %x %x %x\n",
> -                     command[0], command[1], command[2], command[3]);
> +                     cmd.inst,
> +                     (cmd.addr >> 16) & 0xff,
> +                     (cmd.addr >>  8) & 0xff,
> +                     (cmd.addr >>  0) & 0xff);
>
> -               status = spi_flash_cmd_write(spi, command,
> -                                            4, writebuf, writelen);
> +               status = spi_flash_cmd_write(spi, &cmd);
>                 if (status < 0) {
>                         debug("%s: write(compare) send command error!\n",
>                               dev->name);
> @@ -496,7 +499,7 @@ static struct flash_info dataflash_data[] = {
>         { "at45db642d",  0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS},
>  };
>
> -static struct flash_info *jedec_probe(struct spi_slave *spi)
> +static struct flash_info *jedec_probe(struct spi_flash *spi_flash)
>  {
>         int                     tmp;
>         uint8_t                 id[5];
> @@ -513,7 +516,7 @@ static struct flash_info *jedec_probe(struct spi_slave *spi)
>          * That's not an error; only rev C and newer chips handle it, and
>          * only Atmel sells these chips.
>          */
> -       tmp = spi_flash_cmd(spi, CMD_READ_ID, id, sizeof(id));
> +       tmp = spi_flash_cmd(spi_flash, CMD_READ_ID, id, sizeof(id));
>         if (tmp < 0) {
>                 printf("dataflash: error %d reading JEDEC ID\n", tmp);
>                 return ERR_PTR(tmp);
> @@ -532,7 +535,7 @@ static struct flash_info *jedec_probe(struct spi_slave *spi)
>                         tmp++, info++) {
>                 if (info->jedec_id == jedec) {
>                         if (info->flags & SUP_POW2PS) {
> -                               status = dataflash_status(spi);
> +                               status = dataflash_status(spi_flash);
>                                 if (status < 0) {
>                                         debug("dataflash: status error %d\n",
>                                               status);
> @@ -596,7 +599,7 @@ static int spi_dataflash_probe(struct udevice *dev)
>          * Both support the security register, though with different
>          * write procedures.
>          */
> -       info = jedec_probe(spi);
> +       info = jedec_probe(spi_flash);
>         if (IS_ERR(info))
>                 goto err_jedec_probe;
>         if (info != NULL) {
> @@ -611,7 +614,7 @@ static int spi_dataflash_probe(struct udevice *dev)
>         * Older chips support only legacy commands, identifing
>         * capacity using bits in the status byte.
>         */
> -       status = dataflash_status(spi);
> +       status = dataflash_status(spi_flash);
>         if (status <= 0 || status == 0xff) {
>                 printf("dataflash: read status error %d\n", status);
>                 if (status == 0 || status == 0xff)
> diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
> index 839cdbe1b0..5c551089d6 100644
> --- a/drivers/mtd/spi/sf_internal.h
> +++ b/drivers/mtd/spi/sf_internal.h
> @@ -27,7 +27,7 @@ enum spi_nor_option_flags {
>  };
>
>  #define SPI_FLASH_3B_ADDR_LEN          3
> -#define SPI_FLASH_CMD_LEN              (1 + SPI_FLASH_3B_ADDR_LEN)
> +#define SPI_FLASH_CMD_LEN              (1 + SPI_FLASH_3B_ADDR_LEN + 16)
>  #define SPI_FLASH_16MB_BOUN            0x1000000
>
>  /* CFI Manufacture ID's */
> @@ -137,21 +137,21 @@ struct spi_flash_info {
>  extern const struct spi_flash_info spi_flash_ids[];
>
>  /* Send a single-byte command to the device and read the response */
> -int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len);
> +int spi_flash_cmd(struct spi_flash *flash, u8 instr, void *response, size_t len);
>
>  /*
>   * Send a multi-byte command to the device and read the response. Used
>   * for flash array reads, etc.
>   */
> -int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd,
> -               size_t cmd_len, void *data, size_t data_len);
> +int spi_flash_cmd_read(struct spi_flash *flash,
> +                      const struct spi_flash_command *cmd);
>
>  /*
>   * Send a multi-byte command to the device followed by (optional)
>   * data. Used for programming the flash array, etc.
>   */
> -int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
> -               const void *data, size_t data_len);
> +int spi_flash_cmd_write(struct spi_flash *flash,
> +                       const struct spi_flash_command *cmd);
>
>
>  /* Flash erase(sectors) operation, support all possible erase commands */
> @@ -169,13 +169,13 @@ int stm_is_locked(struct spi_flash *flash, u32 ofs, size_t len);
>  /* Enable writing on the SPI flash */
>  static inline int spi_flash_cmd_write_enable(struct spi_flash *flash)
>  {
> -       return spi_flash_cmd(flash->spi, CMD_WRITE_ENABLE, NULL, 0);
> +       return spi_flash_cmd(flash, CMD_WRITE_ENABLE, NULL, 0);
>  }
>
>  /* Disable writing on the SPI flash */
>  static inline int spi_flash_cmd_write_disable(struct spi_flash *flash)
>  {
> -       return spi_flash_cmd(flash->spi, CMD_WRITE_DISABLE, NULL, 0);
> +       return spi_flash_cmd(flash, CMD_WRITE_DISABLE, NULL, 0);
>  }
>
>  /*
> @@ -186,8 +186,8 @@ static inline int spi_flash_cmd_write_disable(struct spi_flash *flash)
>   * - spi_flash_wait_till_ready
>   * - SPI release
>   */
> -int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
> -               size_t cmd_len, const void *buf, size_t buf_len);
> +int spi_flash_write_common(struct spi_flash *flash,
> +                          const struct spi_flash_command *cmd);
>
>  /*
>   * Flash write operation, support all possible write commands.
> @@ -201,8 +201,8 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
>   * Same as spi_flash_cmd_read() except it also claims/releases the SPI
>   * bus. Used as common part of the ->read() operation.
>   */
> -int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd,
> -               size_t cmd_len, void *data, size_t data_len);
> +int spi_flash_read_common(struct spi_flash *flash,
> +                         const struct spi_flash_command *cmd);
>
>  /* Flash read operation, support all possible read commands */
>  int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
> diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
> index 0034a28d5f..80541d0ab4 100644
> --- a/drivers/mtd/spi/spi_flash.c
> +++ b/drivers/mtd/spi/spi_flash.c
> @@ -22,21 +22,15 @@
>
>  DECLARE_GLOBAL_DATA_PTR;
>
> -static void spi_flash_addr(u32 addr, u8 *cmd)
> -{
> -       /* cmd[0] is actual command */
> -       cmd[1] = addr >> 16;
> -       cmd[2] = addr >> 8;
> -       cmd[3] = addr >> 0;
> -}
> -
>  static int read_sr(struct spi_flash *flash, u8 *rs)
>  {
> +       struct spi_flash_command cmd;
>         int ret;
> -       u8 cmd;
>
> -       cmd = CMD_READ_STATUS;
> -       ret = spi_flash_read_common(flash, &cmd, 1, rs, 1);
> +       spi_flash_command_init(&cmd, CMD_READ_STATUS, 0, SPI_FCMD_READ_REG);
> +       cmd.data_len = 1;
> +       cmd.rx_data = rs;

Better to do these command initialization in sf.c just before the
transfer initiate instead of doing it for each I/O operation.

thanks!
-- 
Jagan Teki
Free Software Engineer | www.openedev.com
U-Boot, Linux | Upstream Maintainer
Hyderabad, India.


More information about the U-Boot mailing list