
addr_width is required to configure the flash with 3 and 4 byte addressing, more features will add in future patches.
Cc: Simon Glass sjg@chromium.org Cc: Bin Meng bmeng.cn@gmail.com Cc: Mugunthan V N mugunthanvnm@ti.com Cc: Michal Simek michal.simek@xilinx.com Cc: Siva Durga Prasad Paladugu sivadur@xilinx.com Signed-off-by: Jagan Teki jteki@openedev.com --- drivers/mtd/spi-nor/m25p80.c | 17 +++++++++-------- drivers/mtd/spi-nor/spi-nor.c | 5 +++++ include/linux/mtd/spi-nor.h | 2 ++ 3 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/drivers/mtd/spi-nor/m25p80.c b/drivers/mtd/spi-nor/m25p80.c index a6e9cfe..266407f 100644 --- a/drivers/mtd/spi-nor/m25p80.c +++ b/drivers/mtd/spi-nor/m25p80.c @@ -27,12 +27,13 @@ struct m25p { u8 command[MAX_CMD_SIZE]; };
-static void m25p_addr2cmd(u32 addr, u8 *cmd) +static void m25p_addr2cmd(struct spi_nor *nor, unsigned int addr, u8 *cmd) { - /* cmd[0] is actual command */ - cmd[1] = addr >> 16; - cmd[2] = addr >> 8; - cmd[3] = addr >> 0; + /* opcode is in cmd[0] */ + cmd[1] = addr >> (nor->addr_width * 8 - 8); + cmd[2] = addr >> (nor->addr_width * 8 - 16); + cmd[3] = addr >> (nor->addr_width * 8 - 24); + cmd[4] = addr >> (nor->addr_width * 8 - 32); }
static int m25p80_read_reg(struct spi_nor *nor, u8 cmd, u8 *val, int len) @@ -136,7 +137,7 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len, }
flash->command[0] = nor->read_opcode; - m25p_addr2cmd(from, flash->command); + m25p_addr2cmd(nor, from, flash->command);
if (nor->flags & SNOR_F_U_PAGE) spi->flags |= SPI_XFER_U_PAGE; @@ -171,7 +172,7 @@ static int m25p80_write(struct spi_nor *nor, loff_t to, size_t len, cmd_sz = 1;
flash->command[0] = nor->program_opcode; - m25p_addr2cmd(to, flash->command); + m25p_addr2cmd(nor, to, flash->command);
if (nor->flags & SNOR_F_U_PAGE) spi->flags |= SPI_XFER_U_PAGE; @@ -204,7 +205,7 @@ static int m25p80_erase(struct spi_nor *nor, loff_t offset) }
flash->command[0] = nor->erase_opcode; - m25p_addr2cmd(offset, flash->command); + m25p_addr2cmd(nor, offset, flash->command);
if (nor->flags & SNOR_F_U_PAGE) spi->flags |= SPI_XFER_U_PAGE; diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index cb9ab21..0b3140d 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1032,6 +1032,11 @@ int spi_nor_scan(struct spi_nor *nor) } }
+ if (info->addr_width) + nor->addr_width = info->addr_width; + else + nor->addr_width = 3; + /* read_dummy: dummy byte is determined based on the * dummy cycles of a particular command. * Fast commands - read_dummy = dummy_cycles/8 diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 19a5dd0..b144341 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -171,6 +171,7 @@ extern const struct spi_nor_info spi_nor_ids[]; * @mtd: point to a mtd_info structure * @name: name of the SPI NOR device * @page_size: the page size of the SPI NOR + * @addr_width: number of address bytes * @erase_opcode: the opcode for erasing a sector * @read_opcode: the read opcode * @read_dummy: the dummy bytes needed by the read operation @@ -202,6 +203,7 @@ struct spi_nor { struct mtd_info *mtd; const char *name; u32 page_size; + u8 addr_width; u8 erase_opcode; u8 read_opcode; u8 read_dummy;