Skip to content

Commit f617647

Browse files
committed
Merge tag 'mtd/fixes-for-6.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
Pull MTD fixes from Miquel Raynal: "In the raw NAND subsystem, the major fix prevents using cached reads with devices not supporting it. There was two bug reports about this. Apart from that, three drivers (pl353, arasan and marvell) could sometimes hide page program failures due to their their own program page helper not being fully compliant with the specification (many drivers use the default helpers shared by the core). Adding a missing check prevents these situation. Finally, the Qualcomm driver had a broken error path. In the SPI-NAND subsystem one Micron device used a wrong bitmak reporting possibly corrupted ECC status. Finally, the physmap-core got stripped from its map_rom fallback by mistake, this feature is added back" * tag 'mtd/fixes-for-6.6-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: mtd: rawnand: Ensure the nand chip supports cached reads mtd: rawnand: qcom: Unmap the right resource upon probe failure mtd: rawnand: pl353: Ensure program page operations are successful mtd: rawnand: arasan: Ensure program page operations are successful mtd: spinand: micron: correct bitmask for ecc status mtd: physmap-core: Restore map_rom fallback mtd: rawnand: marvell: Ensure program page operations are successful
2 parents 7da6c04 + f6ca3fb commit f617647

File tree

12 files changed

+73
-5
lines changed

12 files changed

+73
-5
lines changed

drivers/mtd/maps/physmap-core.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,17 @@ static int physmap_flash_probe(struct platform_device *dev)
551551
if (info->probe_type) {
552552
info->mtds[i] = do_map_probe(info->probe_type,
553553
&info->maps[i]);
554+
555+
/* Fall back to mapping region as ROM */
556+
if (!info->mtds[i] && IS_ENABLED(CONFIG_MTD_ROM) &&
557+
strcmp(info->probe_type, "map_rom")) {
558+
dev_warn(&dev->dev,
559+
"map_probe() failed for type %s\n",
560+
info->probe_type);
561+
562+
info->mtds[i] = do_map_probe("map_rom",
563+
&info->maps[i]);
564+
}
554565
} else {
555566
int j;
556567

drivers/mtd/nand/raw/arasan-nand-controller.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
515515
struct mtd_info *mtd = nand_to_mtd(chip);
516516
unsigned int len = mtd->writesize + (oob_required ? mtd->oobsize : 0);
517517
dma_addr_t dma_addr;
518+
u8 status;
518519
int ret;
519520
struct anfc_op nfc_op = {
520521
.pkt_reg =
@@ -561,10 +562,21 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,
561562
}
562563

563564
/* Spare data is not protected */
564-
if (oob_required)
565+
if (oob_required) {
565566
ret = nand_write_oob_std(chip, page);
567+
if (ret)
568+
return ret;
569+
}
566570

567-
return ret;
571+
/* Check write status on the chip side */
572+
ret = nand_status_op(chip, &status);
573+
if (ret)
574+
return ret;
575+
576+
if (status & NAND_STATUS_FAIL)
577+
return -EIO;
578+
579+
return 0;
568580
}
569581

570582
static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf,

drivers/mtd/nand/raw/marvell_nand.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,7 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip,
11651165
.ndcb[2] = NDCB2_ADDR5_PAGE(page),
11661166
};
11671167
unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0);
1168+
u8 status;
11681169
int ret;
11691170

11701171
/* NFCv2 needs more information about the operation being executed */
@@ -1198,7 +1199,18 @@ static int marvell_nfc_hw_ecc_hmg_do_write_page(struct nand_chip *chip,
11981199

11991200
ret = marvell_nfc_wait_op(chip,
12001201
PSEC_TO_MSEC(sdr->tPROG_max));
1201-
return ret;
1202+
if (ret)
1203+
return ret;
1204+
1205+
/* Check write status on the chip side */
1206+
ret = nand_status_op(chip, &status);
1207+
if (ret)
1208+
return ret;
1209+
1210+
if (status & NAND_STATUS_FAIL)
1211+
return -EIO;
1212+
1213+
return 0;
12021214
}
12031215

12041216
static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct nand_chip *chip,
@@ -1627,6 +1639,7 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip,
16271639
int data_len = lt->data_bytes;
16281640
int spare_len = lt->spare_bytes;
16291641
int chunk, ret;
1642+
u8 status;
16301643

16311644
marvell_nfc_select_target(chip, chip->cur_cs);
16321645

@@ -1663,6 +1676,14 @@ static int marvell_nfc_hw_ecc_bch_write_page(struct nand_chip *chip,
16631676
if (ret)
16641677
return ret;
16651678

1679+
/* Check write status on the chip side */
1680+
ret = nand_status_op(chip, &status);
1681+
if (ret)
1682+
return ret;
1683+
1684+
if (status & NAND_STATUS_FAIL)
1685+
return -EIO;
1686+
16661687
return 0;
16671688
}
16681689

drivers/mtd/nand/raw/nand_base.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5110,6 +5110,9 @@ static void rawnand_check_cont_read_support(struct nand_chip *chip)
51105110
{
51115111
struct mtd_info *mtd = nand_to_mtd(chip);
51125112

5113+
if (!chip->parameters.supports_read_cache)
5114+
return;
5115+
51135116
if (chip->read_retries)
51145117
return;
51155118

drivers/mtd/nand/raw/nand_jedec.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ int nand_jedec_detect(struct nand_chip *chip)
9494
goto free_jedec_param_page;
9595
}
9696

97+
if (p->opt_cmd[0] & JEDEC_OPT_CMD_READ_CACHE)
98+
chip->parameters.supports_read_cache = true;
99+
97100
memorg->pagesize = le32_to_cpu(p->byte_per_page);
98101
mtd->writesize = memorg->pagesize;
99102

drivers/mtd/nand/raw/nand_onfi.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,9 @@ int nand_onfi_detect(struct nand_chip *chip)
303303
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
304304
}
305305

306+
if (le16_to_cpu(p->opt_cmd) & ONFI_OPT_CMD_READ_CACHE)
307+
chip->parameters.supports_read_cache = true;
308+
306309
onfi = kzalloc(sizeof(*onfi), GFP_KERNEL);
307310
if (!onfi) {
308311
ret = -ENOMEM;

drivers/mtd/nand/raw/pl35x-nand-controller.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip,
511511
u32 addr1 = 0, addr2 = 0, row;
512512
u32 cmd_addr;
513513
int i, ret;
514+
u8 status;
514515

515516
ret = pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_APB);
516517
if (ret)
@@ -563,6 +564,14 @@ static int pl35x_nand_write_page_hwecc(struct nand_chip *chip,
563564
if (ret)
564565
goto disable_ecc_engine;
565566

567+
/* Check write status on the chip side */
568+
ret = nand_status_op(chip, &status);
569+
if (ret)
570+
goto disable_ecc_engine;
571+
572+
if (status & NAND_STATUS_FAIL)
573+
ret = -EIO;
574+
566575
disable_ecc_engine:
567576
pl35x_smc_set_ecc_mode(nfc, chip, PL35X_SMC_ECC_CFG_MODE_BYPASS);
568577

drivers/mtd/nand/raw/qcom_nandc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3444,7 +3444,7 @@ static int qcom_nandc_probe(struct platform_device *pdev)
34443444
err_aon_clk:
34453445
clk_disable_unprepare(nandc->core_clk);
34463446
err_core_clk:
3447-
dma_unmap_resource(dev, res->start, resource_size(res),
3447+
dma_unmap_resource(dev, nandc->base_dma, resource_size(res),
34483448
DMA_BIDIRECTIONAL, 0);
34493449
return ret;
34503450
}

drivers/mtd/nand/spi/micron.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
#define SPINAND_MFR_MICRON 0x2c
1414

15-
#define MICRON_STATUS_ECC_MASK GENMASK(7, 4)
15+
#define MICRON_STATUS_ECC_MASK GENMASK(6, 4)
1616
#define MICRON_STATUS_ECC_NO_BITFLIPS (0 << 4)
1717
#define MICRON_STATUS_ECC_1TO3_BITFLIPS (1 << 4)
1818
#define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4)

include/linux/mtd/jedec.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ struct jedec_ecc_info {
2121
/* JEDEC features */
2222
#define JEDEC_FEATURE_16_BIT_BUS (1 << 0)
2323

24+
/* JEDEC Optional Commands */
25+
#define JEDEC_OPT_CMD_READ_CACHE BIT(1)
26+
2427
struct nand_jedec_params {
2528
/* rev info and features block */
2629
/* 'J' 'E' 'S' 'D' */

0 commit comments

Comments
 (0)