diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2015-09-01 09:43:54 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2015-09-01 09:43:54 +0200 |
commit | 60fc3e99b52e7ac3282e80ed4124a9a6d1276b23 (patch) | |
tree | 85eff24b87bbf4da2d584b7f58a54a2e946595ff /drivers/mtd/spi-nor | |
parent | 69dccb494a0ee5fececc67f2b7afa7b79368a991 (diff) | |
parent | 746a5530bee37c8d2ffc75609447641b3f3cb55b (diff) | |
download | barebox-60fc3e99b52e7ac3282e80ed4124a9a6d1276b23.tar.gz barebox-60fc3e99b52e7ac3282e80ed4124a9a6d1276b23.tar.xz |
Merge branch 'for-next/mtd'
Diffstat (limited to 'drivers/mtd/spi-nor')
-rw-r--r-- | drivers/mtd/spi-nor/cadence-quadspi.c | 2 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/spi-nor.c | 81 |
2 files changed, 13 insertions, 70 deletions
diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index dce29ca0ea..ff7bb7a5d8 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c @@ -1078,7 +1078,7 @@ static int cqspi_setup_flash(struct device_d *dev, nor->write = cqspi_write; nor->erase = cqspi_erase; - ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD); + ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD, false); if (ret) goto probe_failed; diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 9435424085..b357e5adb4 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -370,85 +370,27 @@ erase_err: static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, size_t len) { - struct spi_nor *nor = mtd_to_spi_nor(mtd); - uint32_t offset = ofs; - uint8_t status_old, status_new; - int ret = 0; - - ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_LOCK); - if (ret) - return ret; - - status_old = read_sr(nor); - - if (offset < mtd->size - (mtd->size / 2)) - status_new = status_old | SR_BP2 | SR_BP1 | SR_BP0; - else if (offset < mtd->size - (mtd->size / 4)) - status_new = (status_old & ~SR_BP0) | SR_BP2 | SR_BP1; - else if (offset < mtd->size - (mtd->size / 8)) - status_new = (status_old & ~SR_BP1) | SR_BP2 | SR_BP0; - else if (offset < mtd->size - (mtd->size / 16)) - status_new = (status_old & ~(SR_BP0 | SR_BP1)) | SR_BP2; - else if (offset < mtd->size - (mtd->size / 32)) - status_new = (status_old & ~SR_BP2) | SR_BP1 | SR_BP0; - else if (offset < mtd->size - (mtd->size / 64)) - status_new = (status_old & ~(SR_BP2 | SR_BP0)) | SR_BP1; - else - status_new = (status_old & ~(SR_BP2 | SR_BP1)) | SR_BP0; - - /* Only modify protection if it will not unlock other areas */ - if ((status_new & (SR_BP2 | SR_BP1 | SR_BP0)) > - (status_old & (SR_BP2 | SR_BP1 | SR_BP0))) { - write_enable(nor); - ret = write_sr(nor, status_new); - if (ret) - goto err; - } - -err: - spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK); - return ret; + return 0; } static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) { struct spi_nor *nor = mtd_to_spi_nor(mtd); - uint32_t offset = ofs; - uint8_t status_old, status_new; - int ret = 0; + uint8_t status; + int ret; ret = spi_nor_lock_and_prep(nor, SPI_NOR_OPS_UNLOCK); if (ret) return ret; - status_old = read_sr(nor); - - if (offset+len > mtd->size - (mtd->size / 64)) - status_new = status_old & ~(SR_BP2 | SR_BP1 | SR_BP0); - else if (offset+len > mtd->size - (mtd->size / 32)) - status_new = (status_old & ~(SR_BP2 | SR_BP1)) | SR_BP0; - else if (offset+len > mtd->size - (mtd->size / 16)) - status_new = (status_old & ~(SR_BP2 | SR_BP0)) | SR_BP1; - else if (offset+len > mtd->size - (mtd->size / 8)) - status_new = (status_old & ~SR_BP2) | SR_BP1 | SR_BP0; - else if (offset+len > mtd->size - (mtd->size / 4)) - status_new = (status_old & ~(SR_BP0 | SR_BP1)) | SR_BP2; - else if (offset+len > mtd->size - (mtd->size / 2)) - status_new = (status_old & ~SR_BP1) | SR_BP2 | SR_BP0; - else - status_new = (status_old & ~SR_BP0) | SR_BP2 | SR_BP1; + status = read_sr(nor); + status &= ~(SR_BP2 | SR_BP1 | SR_BP0); + write_enable(nor); - /* Only modify protection if it will not lock other areas */ - if ((status_new & (SR_BP2 | SR_BP1 | SR_BP0)) < - (status_old & (SR_BP2 | SR_BP1 | SR_BP0))) { - write_enable(nor); - ret = write_sr(nor, status_new); - if (ret) - goto err; - } + ret = write_sr(nor, status); -err: spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK); + return ret; } @@ -928,7 +870,8 @@ static int spi_nor_check(struct spi_nor *nor) return 0; } -int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) +int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode, + bool use_large_blocks) { const struct spi_device_id *id = NULL; struct flash_info *info; @@ -1017,10 +960,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS /* prefer "small sector" erase if possible */ - if (info->flags & SECT_4K) { + if (info->flags & SECT_4K && !use_large_blocks) { nor->erase_opcode = SPINOR_OP_BE_4K; mtd->erasesize = 4096; - } else if (info->flags & SECT_4K_PMC) { + } else if (info->flags & SECT_4K_PMC && !use_large_blocks) { nor->erase_opcode = SPINOR_OP_BE_4K_PMC; mtd->erasesize = 4096; } else |