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; }