summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/spi-nor
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2015-09-01 09:43:54 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2015-09-01 09:43:54 +0200
commit60fc3e99b52e7ac3282e80ed4124a9a6d1276b23 (patch)
tree85eff24b87bbf4da2d584b7f58a54a2e946595ff /drivers/mtd/spi-nor
parent69dccb494a0ee5fececc67f2b7afa7b79368a991 (diff)
parent746a5530bee37c8d2ffc75609447641b3f3cb55b (diff)
downloadbarebox-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.c2
-rw-r--r--drivers/mtd/spi-nor/spi-nor.c81
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