summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/spi/spi-nor-core.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index eb49a6c11c..6e7fc2311e 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -1594,6 +1594,7 @@ struct sfdp_parameter_header {
#define SFDP_BFPT_ID 0xff00 /* Basic Flash Parameter Table */
#define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */
+#define SFDP_SST_ID 0x01bf /* Manufacturer specific Table */
#define SFDP_SIGNATURE 0x50444653U
#define SFDP_JESD216_MAJOR 1
@@ -1974,6 +1975,34 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
}
/**
+ * spi_nor_parse_microchip_sfdp() - parse the Microchip manufacturer specific
+ * SFDP table.
+ * @nor: pointer to a 'struct spi_nor'.
+ * @param_header: pointer to the SFDP parameter header.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int
+spi_nor_parse_microchip_sfdp(struct spi_nor *nor,
+ const struct sfdp_parameter_header *param_header)
+{
+ size_t size;
+ u32 addr;
+ int ret;
+
+ size = param_header->length * sizeof(u32);
+ addr = SFDP_PARAM_HEADER_PTP(param_header);
+
+ nor->manufacturer_sfdp = devm_kmalloc(nor->dev, size, GFP_KERNEL);
+ if (!nor->manufacturer_sfdp)
+ return -ENOMEM;
+
+ ret = spi_nor_read_sfdp(nor, addr, size, nor->manufacturer_sfdp);
+
+ return ret;
+}
+
+/**
* spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters.
* @nor: pointer to a 'struct spi_nor'
* @params: pointer to the 'struct spi_nor_flash_parameter' to be
@@ -2069,12 +2098,25 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
dev_info(dev, "non-uniform erase sector maps are not supported yet.\n");
break;
+ case SFDP_SST_ID:
+ err = spi_nor_parse_microchip_sfdp(nor, param_header);
+ break;
+
default:
break;
}
- if (err)
- goto exit;
+ if (err) {
+ dev_warn(dev, "Failed to parse optional parameter table: %04x\n",
+ SFDP_PARAM_HEADER_ID(param_header));
+ /*
+ * Let's not drop all information we extracted so far
+ * if optional table parsers fail. In case of failing,
+ * each optional parser is responsible to roll back to
+ * the previously known spi_nor data.
+ */
+ err = 0;
+ }
}
exit: