summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/spi/spi_flash.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 34f68881ed..51e28bf07b 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -113,6 +113,27 @@ static int write_cr(struct spi_flash *flash, u8 wc)
#endif
#ifdef CONFIG_SPI_FLASH_BAR
+/*
+ * This "clean_bar" is necessary in a situation when one was accessing
+ * spi flash memory > 16 MiB by using Bank Address Register's BA24 bit.
+ *
+ * After it the BA24 bit shall be cleared to allow access to correct
+ * memory region after SW reset (by calling "reset" command).
+ *
+ * Otherwise, the BA24 bit may be left set and then after reset, the
+ * ROM would read/write/erase SPL from 16 MiB * bank_sel address.
+ */
+static int clean_bar(struct spi_flash *flash)
+{
+ u8 cmd, bank_sel = 0;
+
+ if (flash->bank_curr == 0)
+ return 0;
+ cmd = flash->bank_write_cmd;
+
+ return spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1);
+}
+
static int write_bar(struct spi_flash *flash, u32 offset)
{
u8 cmd, bank_sel;
@@ -339,6 +360,10 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
len -= erase_size;
}
+#ifdef CONFIG_SPI_FLASH_BAR
+ ret = clean_bar(flash);
+#endif
+
return ret;
}
@@ -397,6 +422,10 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
offset += chunk_len;
}
+#ifdef CONFIG_SPI_FLASH_BAR
+ ret = clean_bar(flash);
+#endif
+
return ret;
}
@@ -500,6 +529,10 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
data += read_len;
}
+#ifdef CONFIG_SPI_FLASH_BAR
+ ret = clean_bar(flash);
+#endif
+
free(cmd);
return ret;
}