diff options
Diffstat (limited to 'drivers/mtd/spi/macronix.c')
-rw-r--r-- | drivers/mtd/spi/macronix.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c index 96fd5f0..dacbc28 100644 --- a/drivers/mtd/spi/macronix.c +++ b/drivers/mtd/spi/macronix.c @@ -117,6 +117,45 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = { }, }; +static int macronix_write_status(struct spi_flash *flash, u8 sr) +{ + u8 cmd; + int ret; + + ret = spi_flash_cmd_write_enable(flash); + if (ret < 0) { + debug("SF: enabling write failed\n"); + return ret; + } + + cmd = CMD_MX25XX_WRSR; + ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &sr, 1); + if (ret) { + debug("SF: fail to write status register\n"); + return ret; + } + + ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT); + if (ret < 0) { + debug("SF: write status register timed out\n"); + return ret; + } + + return 0; +} + +static int macronix_unlock(struct spi_flash *flash) +{ + int ret; + + /* Enable status register writing and clear BP# bits */ + ret = macronix_write_status(flash, 0); + if (ret) + debug("SF: fail to disable write protection\n"); + + return ret; +} + static int macronix_erase(struct spi_flash *flash, u32 offset, size_t len) { return spi_flash_cmd_erase(flash, CMD_MX25XX_BE, offset, len); @@ -157,5 +196,8 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode) * params->sectors_per_block; flash->size = flash->sector_size * params->nr_blocks; + /* Clear BP# bits for read-only flash */ + macronix_unlock(flash); + return flash; } |