aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.4/1081-mtd-spi-nor-provide-default-erase_sector-implementat.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.4/1081-mtd-spi-nor-provide-default-erase_sector-implementat.patch')
-rw-r--r--target/linux/layerscape/patches-4.4/1081-mtd-spi-nor-provide-default-erase_sector-implementat.patch105
1 files changed, 105 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-4.4/1081-mtd-spi-nor-provide-default-erase_sector-implementat.patch b/target/linux/layerscape/patches-4.4/1081-mtd-spi-nor-provide-default-erase_sector-implementat.patch
new file mode 100644
index 0000000000..8becdd2905
--- /dev/null
+++ b/target/linux/layerscape/patches-4.4/1081-mtd-spi-nor-provide-default-erase_sector-implementat.patch
@@ -0,0 +1,105 @@
+From 56bd0e13d8bc3b4486251b10ac9d2ba7434c21ee Mon Sep 17 00:00:00 2001
+From: Brian Norris <computersforpeace@gmail.com>
+Date: Tue, 10 Nov 2015 12:15:27 -0800
+Subject: [PATCH 081/113] mtd: spi-nor: provide default erase_sector
+ implementation
+
+Some spi-nor drivers perform sector erase by duplicating their
+write_reg() command. Let's not require that the driver fill this out,
+and provide a default instead.
+
+Tested on m25p80.c and Medatek's MT8173 SPI NOR flash driver.
+
+Signed-off-by: Brian Norris <computersforpeace@gmail.com>
+---
+ drivers/mtd/spi-nor/spi-nor.c | 37 +++++++++++++++++++++++++++++++++----
+ include/linux/mtd/spi-nor.h | 3 ++-
+ 2 files changed, 35 insertions(+), 5 deletions(-)
+
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -38,6 +38,7 @@
+ #define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ)
+
+ #define SPI_NOR_MAX_ID_LEN 6
++#define SPI_NOR_MAX_ADDR_WIDTH 4
+
+ struct flash_info {
+ char *name;
+@@ -313,6 +314,29 @@ static void spi_nor_unlock_and_unprep(st
+ }
+
+ /*
++ * Initiate the erasure of a single sector
++ */
++static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
++{
++ u8 buf[SPI_NOR_MAX_ADDR_WIDTH];
++ int i;
++
++ if (nor->erase)
++ return nor->erase(nor, addr);
++
++ /*
++ * Default implementation, if driver doesn't have a specialized HW
++ * control
++ */
++ for (i = nor->addr_width - 1; i >= 0; i--) {
++ buf[i] = addr & 0xff;
++ addr >>= 8;
++ }
++
++ return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width);
++}
++
++/*
+ * Erase an address range on the nor chip. The address range may extend
+ * one or more erase sectors. Return an error is there is a problem erasing.
+ */
+@@ -371,10 +395,9 @@ static int spi_nor_erase(struct mtd_info
+ while (len) {
+ write_enable(nor);
+
+- if (nor->erase(nor, addr)) {
+- ret = -EIO;
++ ret = spi_nor_erase_sector(nor, addr);
++ if (ret)
+ goto erase_err;
+- }
+
+ addr += mtd->erasesize;
+ len -= mtd->erasesize;
+@@ -1098,7 +1121,7 @@ static int set_quad_mode(struct spi_nor
+ static int spi_nor_check(struct spi_nor *nor)
+ {
+ if (!nor->dev || !nor->read || !nor->write ||
+- !nor->read_reg || !nor->write_reg || !nor->erase) {
++ !nor->read_reg || !nor->write_reg) {
+ pr_err("spi-nor: please fill all the necessary fields!\n");
+ return -EINVAL;
+ }
+@@ -1299,6 +1322,12 @@ int spi_nor_scan(struct spi_nor *nor, co
+ nor->addr_width = 3;
+ }
+
++ if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) {
++ dev_err(dev, "address width is too large: %u\n",
++ nor->addr_width);
++ return -EINVAL;
++ }
++
+ nor->read_dummy = spi_nor_read_dummy_cycles(nor);
+
+ dev_info(dev, "%s (%lld Kbytes)\n", info->name,
+--- a/include/linux/mtd/spi-nor.h
++++ b/include/linux/mtd/spi-nor.h
+@@ -142,7 +142,8 @@ enum spi_nor_option_flags {
+ * @read: [DRIVER-SPECIFIC] read data from the SPI NOR
+ * @write: [DRIVER-SPECIFIC] write data to the SPI NOR
+ * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR
+- * at the offset @offs
++ * at the offset @offs; if not provided by the driver,
++ * spi-nor will send the erase opcode via write_reg()
+ * @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR
+ * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR
+ * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is