From b69beae7b5f97108aedef1e6bd919214810b664e Mon Sep 17 00:00:00 2001 From: Yunhui Cui Date: Thu, 28 Apr 2016 16:11:14 +0800 Subject: mtd: spi-nor: fsl-quad: Add flash S25FS extra support There are some boards have the same QSPI controller but have different vendor falsh, So as to controller can use the same compatible and share the driver, Just for different flash to do the appropriate adaptation. Based on this, we need add the vendor field in spi-nor, Because we will use the field to distribute corresponding LUT for different flash operations. Signed-off-by: Yunhui Cui Signed-off-by: Yuan Yao diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index fea7173..8301bcc 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c @@ -213,6 +213,9 @@ #define QUADSPI_MIN_IOMAP SZ_4M +#define FLASH_VENDOR_SPANSION_FS "s25fs" +#define SPANSION_S25FS_FAMILY (1 << 1) + enum fsl_qspi_devtype { FSL_QUADSPI_VYBRID, FSL_QUADSPI_IMX6SX, @@ -329,6 +332,18 @@ static inline int has_added_amba_base_internal(struct fsl_qspi *q) return q->devtype_data->driver_data & QUADSPI_AMBA_BASE_INTERNAL; } +static u32 fsl_get_nor_vendor(struct spi_nor *nor) +{ + u32 vendor_id; + + if (nor->vendor) { + if (memcmp(nor->vendor, FLASH_VENDOR_SPANSION_FS, + sizeof(FLASH_VENDOR_SPANSION_FS) - 1)) + vendor_id = SPANSION_S25FS_FAMILY; + } + return vendor_id; +} + /* * R/W functions for big- or little-endian registers: * The qSPI controller's endian is independent of the CPU core's endian. @@ -394,13 +409,15 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) int rxfifo = q->devtype_data->rxfifo; u32 lut_base; int i; - const struct fsl_qspi_devtype_data *devtype_data = q->devtype_data; + u32 vendor; struct spi_nor *nor = &q->nor[0]; u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT; u8 read_op = nor->read_opcode; u8 read_dm = nor->read_dummy; + vendor = fsl_get_nor_vendor(nor); + fsl_qspi_unlock_lut(q); /* Clear all the LUT table */ @@ -510,7 +527,8 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q) * use the same value 0x65. But it indicates different meaning. */ lut_base = SEQID_RDAR_OR_RD_EVCR * 4; - if (devtype_data->devtype == FSL_QUADSPI_LS2080A) { + + if (vendor == SPANSION_S25FS_FAMILY) { /* * Read any device register. * Used for Spansion S25FS-S family flash only. diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 21dde52..3915f08 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1370,6 +1370,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) if (!mtd->name) mtd->name = dev_name(dev); + if (info->name) + nor->vendor = info->name; mtd->priv = nor; mtd->type = MTD_NORFLASH; mtd->writesize = 1; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index db3fe42..f556890 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -171,6 +171,7 @@ struct spi_nor { bool sst_write_second; u32 flags; u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE]; + char *vendor; int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops); void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops); -- cgit v0.10.2