summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/spi-nor/core.c
diff options
context:
space:
mode:
authorMichael Walle <michael@walle.cc>2022-08-11 00:06:53 +0200
committerTudor Ambarus <tudor.ambarus@microchip.com>2022-11-21 15:37:16 +0200
commit773bbe10449731c9525457873e0c2342e5cf883b (patch)
treea435d310e5d41d2db99112f7a0a18303a521f0fd /drivers/mtd/spi-nor/core.c
parent39eece67a3cf027aa5b39d7da5feadc4711504e6 (diff)
downloadlinux-773bbe10449731c9525457873e0c2342e5cf883b.tar.bz2
mtd: spi-nor: add generic flash driver
Our SFDP parsing is everything we need to support all basic operations of a flash device. If the flash isn't found in our in-kernel flash database, gracefully fall back to a driver described solely by its SFDP tables. Signed-off-by: Michael Walle <michael@walle.cc> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> Tested-by: Tudor Ambarus <tudor.ambarus@microchip.com> Reviewed-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com> Link: https://lore.kernel.org/r/20220810220654.1297699-7-michael@walle.cc
Diffstat (limited to 'drivers/mtd/spi-nor/core.c')
-rw-r--r--drivers/mtd/spi-nor/core.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 2bdc5b50d8da..71b9bcd8991d 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1634,6 +1634,16 @@ static const struct spi_nor_manufacturer *manufacturers[] = {
&spi_nor_xmc,
};
+static const struct flash_info spi_nor_generic_flash = {
+ .name = "spi-nor-generic",
+ /*
+ * JESD216 rev A doesn't specify the page size, therefore we need a
+ * sane default.
+ */
+ .page_size = 256,
+ .parse_sfdp = true,
+};
+
static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
const u8 *id)
{
@@ -1672,6 +1682,14 @@ static const struct flash_info *spi_nor_detect(struct spi_nor *nor)
return ERR_PTR(-ENOMEM);
info = spi_nor_match_id(nor, id);
+
+ /* Fallback to a generic flash described only by its SFDP data. */
+ if (!info) {
+ ret = spi_nor_check_sfdp_signature(nor);
+ if (!ret)
+ info = &spi_nor_generic_flash;
+ }
+
if (!info) {
dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
SPI_NOR_MAX_ID_LEN, id);
@@ -2098,8 +2116,12 @@ static int spi_nor_select_pp(struct spi_nor *nor,
* spi_nor_select_uniform_erase() - select optimum uniform erase type
* @map: the erase map of the SPI NOR
* @wanted_size: the erase type size to search for. Contains the value of
- * info->sector_size or of the "small sector" size in case
- * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined.
+ * info->sector_size, the "small sector" size in case
+ * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined or 0 if
+ * there is no information about the sector size. The
+ * latter is the case if the flash parameters are parsed
+ * solely by SFDP, then the largest supported erase type
+ * is selected.
*
* Once the optimum uniform sector erase command is found, disable all the
* other.